Browse Source

Fix interaction bugs.

master
t123yh 7 years ago
parent
commit
6062298f46
  1. 1
      src/daemon/judge/index.ts
  2. 8
      src/daemon/judge/interaction.ts
  3. 4
      src/daemon/judge/standard.ts
  4. 4
      src/daemon/judge/submit-answer.ts
  5. 24
      src/runner/judge.ts

1
src/daemon/judge/index.ts

@ -32,6 +32,7 @@ export async function judge(
}
let judger: JudgerBase;
console.log("Task typ: " + task.type);
if (task.type === ProblemType.Standard) {
judger = new StandardJudger(testData, task.param as StandardJudgeParameter, task.priority);
} else if (task.type === ProblemType.AnswerSubmission) {

8
src/daemon/judge/interaction.ts

@ -26,7 +26,7 @@ export class InteractionJudger extends JudgerBase {
async preprocessTestData(): Promise<void> {
if (this.testData.interactor != null) {
winston.verbose("Compiling special judge.");
winston.verbose("Compiling interactor.");
const [interactorExecutableName, interactorResult] = await compile(this.testData.interactor.sourceCode,
this.testData.interactor.language, null, this.priority);
if (interactorResult.status !== TaskStatus.Done) {
@ -69,9 +69,9 @@ export class InteractionJudger extends JudgerBase {
// We do not have to create a InteractionRunResult
const [inputContent, outputContent, runResult]: [string, string, StandardRunResult] = await Promise.all([
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input), Cfg.dataDisplayLimit),
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output), Cfg.dataDisplayLimit),
runTask({ type: RPCTaskType.RunStandard, task: task }, this.priority, started)
readFileLength(curCase.input ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input) : null, Cfg.dataDisplayLimit),
readFileLength(curCase.output ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output) : null, Cfg.dataDisplayLimit),
runTask({ type: RPCTaskType.RunInteraction, task: task }, this.priority, started)
]) as any;
return {

4
src/daemon/judge/standard.ts

@ -70,8 +70,8 @@ export class StandardJudger extends JudgerBase {
};
const [inputContent, outputContent, runResult]: [string, string, StandardRunResult] = await Promise.all([
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input), Cfg.dataDisplayLimit),
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output), Cfg.dataDisplayLimit),
readFileLength(curCase.input ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input) : null, Cfg.dataDisplayLimit),
readFileLength(curCase.output ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output) : null, Cfg.dataDisplayLimit),
runTask({ type: RPCTaskType.RunStandard, task: task }, this.priority, started)
]) as any;

4
src/daemon/judge/submit-answer.ts

@ -77,8 +77,8 @@ export class AnswerSubmissionJudger extends JudgerBase {
}
const [inputContent, outputContent, runResult]: [string, string, AnswerSubmissionRunResult] = await Promise.all([
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input), Cfg.dataDisplayLimit),
readFileLength(pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output), Cfg.dataDisplayLimit),
readFileLength(curCase.input ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.input) : null, Cfg.dataDisplayLimit),
readFileLength(curCase.output ? pathLib.join(Cfg.testDataDirectory, this.testData.name, curCase.output) : null, Cfg.dataDisplayLimit),
runTask({ type: RPCTaskType.RunSubmitAnswer, task: task }, this.priority, started)
]) as any;

24
src/runner/judge.ts

@ -1,8 +1,9 @@
import pathLib = require('path');
import randomString = require('randomstring');
import util = require('util');
import fse = require('fs-extra');
import winston = require('winston');
import syspipe = require('syspipe');
const syspipe = require('syspipe');
import { SandboxStatus } from 'simple-sandbox/lib/interfaces';
import { TestcaseResultType, StandardRunTask, StandardRunResult, InteractionRunTask, AnswerSubmissionRunTask, AnswerSubmissionRunResult } from '../interfaces';
@ -285,7 +286,7 @@ export async function judgeInteraction(task: InteractionRunTask)
winston.debug("Fetching user binary...");
const [userBinaryDirectory, userLanguage, userCode] = await fetchBinary(task.userExecutableName);
winston.debug("Fetching interactor binary...");
const [interactorBinaryDirectory, interactorLanguage] = await fetchBinary(task.userExecutableName);
const [interactorBinaryDirectory, interactorLanguage] = await fetchBinary(task.interactorExecutableName);
pipe1 = syspipe.pipe(),
pipe2 = syspipe.pipe();
@ -311,8 +312,6 @@ export async function judgeInteraction(task: InteractionRunTask)
const [interactorResult, runResult] = await Promise.all([interactorTaskPromise
.then((result) => { stopUser(); return result; }, (err) => { stopUser(); return Promise.reject(err); }), userProgramTaskPromise]);
const userError = await readFileLength(pathLib.join(workingDir, tempErrFile), Cfg.stderrDisplayLimit);
const time = Math.round(runResult.result.time / 1e6),
memory = runResult.result.memory / 1024;
@ -327,6 +326,7 @@ export async function judgeInteraction(task: InteractionRunTask)
message = `Killed: ${signals[runResult.result.code]}`;
status = TestcaseResultType.RuntimeError;
} else if (runResult.result.status !== SandboxStatus.OK) {
message = "Warning: corrupt sandbox result " + util.inspect(runResult.result);
status = TestcaseResultType.RuntimeError;
} else {
message = `Exited with return code ${runResult.result.code}`;
@ -344,7 +344,7 @@ export async function judgeInteraction(task: InteractionRunTask)
time: time,
memory: time,
userOutput: null,
userError: userError,
userError: await readFileLength(pathLib.join(workingDir, tempErrFile), Cfg.stderrDisplayLimit),
spjMessage: await readFileLength(pathLib.join(spjWorkingDir, tempErrFile), Cfg.stderrDisplayLimit)
};
@ -352,21 +352,23 @@ export async function judgeInteraction(task: InteractionRunTask)
let score = 0;
if (status == null) {
const scoreString = await tryReadFile(spjWorkingDir + '/score.txt');
let score = Number(scoreString);
if ((!scoreString) || isNaN(score)) {
const rawScore = Number(scoreString);
if ((!scoreString) || isNaN(rawScore)) {
score = null;
status = TestcaseResultType.JudgementFailed;
message = `Interactor returned a non-number score ${scoreString}`;
} else if (score === -1) {
score = 0;
status = TestcaseResultType.InvalidInteraction;
} else {
score = score;
status = getStatusByScore(score);
score = rawScore;
status = getStatusByScore(rawScore);
}
}
winston.debug(`Interaction problem judge succeeded, score = ${score}`);
return Object.assign(partialResult, {
result: status,
scoringRate: score / spjFullScore
scoringRate: score / spjFullScore,
systemMessage: message
});
} finally {
const closePipe = async (p) => {

Loading…
Cancel
Save