judge: remove useless suffix

This commit is contained in:
undefined committed 2022-09-06 13:02:46 +08:00
1 parent 805c8e4cd3
commit 7f967060cd
12 files changed
+61 -60

No files matched your search

+14 -3
View File
@@ -1,10 +1,21 @@
/* eslint-disable no-template-curly-in-string */
import { STATUS } from '@hydrooj/utils/lib/status';
import { FormatError, SystemError } from './error';
import { CheckConfig } from './interface';
import { run } from './sandbox';
import { CopyInFile, run } from './sandbox';
import { parse } from './testlib';
export interface CheckConfig {
execute: string;
input: CopyInFile;
output: CopyInFile;
user_stdout: CopyInFile;
user_stderr: CopyInFile;
copyIn: Record<string, CopyInFile>;
score: number;
detail: boolean;
env?: Record<string, string>;
}
type Checker = (config: CheckConfig) => Promise<{
status: number,
score: number,
@@ -202,4 +213,4 @@ const checkers: Record<string, Checker> = new Proxy({
},
});
export = checkers;
export default checkers;
+4 -4
View File
@@ -71,8 +71,8 @@ export const runFlow = async (ctx: Context, task: Task) => {
const tasks = [];
ctx.total_status = 0;
ctx.total_score = 0;
ctx.total_memory_usage_kb = 0;
ctx.total_time_usage_ms = 0;
ctx.total_memory = 0;
ctx.total_time = 0;
ctx.rerun = getConfig('rerun') || 0;
ctx.queue = new Queue({ concurrency: getConfig('singleTaskParallelism') });
ctx.failed = {};
@@ -90,7 +90,7 @@ export const runFlow = async (ctx: Context, task: Task) => {
ctx.end({
status: ctx.total_status,
score: ctx.total_score,
time: Math.floor(ctx.total_time_usage_ms * 1000000) / 1000000,
memory: ctx.total_memory_usage_kb,
time: Math.floor(ctx.total_time * 1000000) / 1000000,
memory: ctx.total_memory,
});
};
+1 -1
View File
@@ -19,7 +19,7 @@ const logger = new Logger('judge');
const session = {
config: { detail: system.get('hydrojudge.detail') },
async fetchCodeFile(name: string) {
async fetchFile(name: string) {
const target = path.join('/tmp/hydro/judge', name.replace(/\//g, '_'));
await storage.get(`submission/${name}`, target);
return target;
+1 -1
View File
@@ -105,7 +105,7 @@ export default class Hydro {
return filePath;
}
async fetchCodeFile(name: string) {
async fetchFile(name: string) {
const res = await this.axios.post('judge/code', { id: name });
const f = await this.axios.get(res.data.url, { responseType: 'stream' })
.catch((e) => new Error(`DownloadFail(${name}): ${e.message}`));
-12
View File
@@ -6,15 +6,3 @@ export interface Execute {
copyIn: Record<string, CopyInFile>;
time?: number;
}
export interface CheckConfig {
execute: string;
input: CopyInFile;
output: CopyInFile;
user_stdout: CopyInFile;
user_stderr: CopyInFile;
copyIn: Record<string, CopyInFile>;
score: number;
detail: boolean;
env?: Record<string, string>;
}
+9 -9
View File
@@ -23,7 +23,7 @@ function judgeCase(c: NormalizedCase, sid: string) {
const copyIn = { ...ctx.execute.copyIn };
if (filename) copyIn[`${filename}.in`] = c.input ? { src: c.input } : { content: '' };
const copyOutCached = filename ? [`${filename}.out?`] : [];
const stdin = filename ? null : c.input;
const stdin = filename ? null : { src: c.input };
const res = await run(
ctx.execute.execute,
{
@@ -35,7 +35,7 @@ function judgeCase(c: NormalizedCase, sid: string) {
cacheStdoutAndStderr: true,
},
);
const { code, time_usage_ms, memory_usage_kb } = res;
const { code, time, memory } = res;
let { status } = res;
let stdout: CmdFile = { fileId: res.fileIds[filename ? `${filename}.out` : 'stdout'] };
const stderr = { fileId: res.fileIds['stderr'] };
@@ -43,9 +43,9 @@ function judgeCase(c: NormalizedCase, sid: string) {
let message: any = '';
let score = 0;
if (status === STATUS.STATUS_ACCEPTED) {
if (time_usage_ms > c.time * ctx.execute.time) {
if (time > c.time * ctx.execute.time) {
status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
} else if (memory_usage_kb > c.memory * 1024) {
} else if (memory > c.memory * 1024) {
status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
} else {
({ status, score, message } = await checkers[ctx.config.checker_type]({
@@ -75,16 +75,16 @@ function judgeCase(c: NormalizedCase, sid: string) {
ctxSubtask.score = Score[ctxSubtask.subtask.type](ctxSubtask.score, score);
ctxSubtask.status = Math.max(ctxSubtask.status, status);
if (ctxSubtask.status > STATUS.STATUS_ACCEPTED) ctx.failed[sid] = true;
ctx.total_time_usage_ms += time_usage_ms;
ctx.total_memory_usage_kb = Math.max(ctx.total_memory_usage_kb, memory_usage_kb);
ctx.total_time += time;
ctx.total_memory = Math.max(ctx.total_memory, memory);
ctx.next({
case: {
id: c.id,
subtaskId: ctxSubtask.subtask.id,
status,
score,
time: time_usage_ms,
memory: memory_usage_kb,
time,
memory,
message,
},
addProgress: 100 / ctx.config.count,
@@ -98,7 +98,7 @@ function judgeCase(c: NormalizedCase, sid: string) {
const r = await run(langConfig.analysis, {
copyIn: {
...copyIn,
input: stdin ? { src: stdin } : { content: '' },
input: stdin || { content: '' },
[langConfig.code_file || 'foo']: ctx.code,
compile: { content: langConfig.compile || '' },
execute: { content: langConfig.execute || '' },
+7 -7
View File
@@ -19,7 +19,7 @@ function judgeCase(c: NormalizedCase) {
return async (ctx: Context, ctxSubtask: ContextSubTask) => {
ctx.executeInteractor.copyIn.in = c.input ? { src: c.input } : { content: '' };
ctx.executeInteractor.copyIn.out = c.output ? { src: c.output } : { content: '' };
const [{ code, time_usage_ms, memory_usage_kb }, resInteractor] = await runPiped(
const [{ code, time, memory }, resInteractor] = await runPiped(
{
execute: ctx.executeUser.execute,
copyIn: ctx.executeUser.copyIn,
@@ -39,9 +39,9 @@ function judgeCase(c: NormalizedCase) {
let status: number;
let score = 0;
let message: any = '';
if (time_usage_ms > c.time * ctx.executeUser.time) {
if (time > c.time * ctx.executeUser.time) {
status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
} else if (memory_usage_kb > c.memory * 1024) {
} else if (memory > c.memory * 1024) {
status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
} else if ((code && code !== 13/* Broken Pipe */) || (code === 13 && !resInteractor.code)) {
status = STATUS.STATUS_RUNTIME_ERROR;
@@ -56,8 +56,8 @@ function judgeCase(c: NormalizedCase) {
}
ctxSubtask.score = Score[ctxSubtask.subtask.type](ctxSubtask.score, score);
ctxSubtask.status = Math.max(ctxSubtask.status, status);
ctx.total_time_usage_ms += time_usage_ms;
ctx.total_memory_usage_kb = Math.max(ctx.total_memory_usage_kb, memory_usage_kb);
ctx.total_time += time;
ctx.total_memory = Math.max(ctx.total_memory, memory);
ctx.next({
status: STATUS.STATUS_JUDGING,
case: {
@@ -65,8 +65,8 @@ function judgeCase(c: NormalizedCase) {
subtaskId: ctxSubtask.subtask.id,
status,
score,
time: time_usage_ms,
memory: memory_usage_kb,
time,
memory,
message,
},
addProgress: 100 / ctx.config.count,
+2 -2
View File
@@ -8,8 +8,8 @@ export type Context = JudgeTask & RuntimeContext;
export interface RuntimeContext {
total_score?: number;
total_status?: number;
total_time_usage_ms?: number;
total_memory_usage_kb?: number;
total_time?: number;
total_memory?: number;
queue?: PQueue;
errored?: boolean;
+9 -11
View File
@@ -52,14 +52,12 @@ export const judge = async (ctx: Context) => {
const { filename } = ctx.config;
if (filename) copyIn[`${filename}.in`] = { content: ctx.input };
const copyOut = filename ? [`${filename}.out?`] : [];
const stdin = path.resolve(ctx.tmpdir, '0.in');
await fs.writeFile(stdin, ctx.input || '');
const stdout = path.resolve(ctx.tmpdir, '0.out');
const stderr = path.resolve(ctx.tmpdir, '0.err');
const res = await run(
ctx.execute.execute,
{
stdin: filename ? null : stdin,
stdin: filename ? null : { content: ctx.input },
stdout: filename ? null : stdout,
stderr,
copyIn,
@@ -68,14 +66,14 @@ export const judge = async (ctx: Context) => {
memory: parseMemoryMB(ctx.config.memory || '128m'),
},
);
const { code, time_usage_ms, memory_usage_kb } = res;
const { code, time, memory } = res;
let { status } = res;
if (!fs.existsSync(stdout)) fs.writeFileSync(stdout, '');
const message: string[] = [];
if (status === STATUS.STATUS_ACCEPTED) {
if (time_usage_ms > parseTimeMS(ctx.config.time || '1s') * ctx.execute.time) {
if (time > parseTimeMS(ctx.config.time || '1s') * ctx.execute.time) {
status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
} else if (memory_usage_kb > parseMemoryMB(ctx.config.memory || '128m') * 1024) {
} else if (memory > parseMemoryMB(ctx.config.memory || '128m') * 1024) {
status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
}
} else if (code) {
@@ -91,8 +89,8 @@ export const judge = async (ctx: Context) => {
subtaskId: 0,
status,
score: 100,
time: time_usage_ms,
memory: memory_usage_kb,
time,
memory,
message: message.join('\n').substring(0, 102400),
},
});
@@ -104,7 +102,7 @@ export const judge = async (ctx: Context) => {
const r = await run(langConfig.analysis, {
copyIn: {
...copyIn,
input: { src: stdin },
input: { content: ctx.input },
[langConfig.code_file || 'foo']: ctx.code,
compile: { content: langConfig.compile || '' },
execute: { content: langConfig.execute || '' },
@@ -130,7 +128,7 @@ export const judge = async (ctx: Context) => {
ctx.end({
status,
score: status === STATUS.STATUS_ACCEPTED ? 100 : 0,
time: Math.floor(time_usage_ms * 1000000) / 1000000,
memory: memory_usage_kb,
time: Math.floor(time * 1000000) / 1000000,
memory,
});
};
+10 -8
View File
@@ -30,7 +30,7 @@ const statusMap: Map<SandboxStatus, number> = new Map([
interface Parameter {
time?: number;
stdin?: string;
stdin?: CopyInFile;
stdout?: string;
stderr?: string;
execute?: string;
@@ -46,8 +46,10 @@ interface Parameter {
interface SandboxAdaptedResult {
status: number;
code: number;
time_usage_ms: number;
memory_usage_kb?: number;
/** in miliseconds */
time: number;
/** in kilobytes */
memory?: number;
files: Record<string, string>;
fileIds?: Record<string, string>;
stdout?: string;
@@ -72,7 +74,7 @@ function proc({
time = 16000,
memory = parseMemoryMB(getConfig('memoryMax')),
processLimit = getConfig('processLimit'),
stdin = '', copyIn = {}, copyOut = [], copyOutCached = [],
stdin = { content: '' }, copyIn = {}, copyOut = [], copyOutCached = [],
cacheStdoutAndStderr = false,
env = {},
}: Parameter = {}): Cmd {
@@ -89,7 +91,7 @@ function proc({
args: parseArgs(execute),
env: [...getConfig('env').split('\n'), ...Object.keys(env).map((i) => `${i}=${env[i].replace(/=/g, '\\=')}`)],
files: [
stdin ? { src: stdin } : { content: '' },
stdin,
{ name: 'stdout', max: Math.floor(1024 * 1024 * size) },
{ name: 'stderr', max: Math.floor(1024 * 1024 * size) },
],
@@ -110,12 +112,12 @@ async function adaptResult(result: SandboxResult, params: Parameter): Promise<Sa
// FIXME: Signalled?
const ret: SandboxAdaptedResult = {
status: statusMap.get(result.status) || STATUS.STATUS_ACCEPTED,
time_usage_ms: result.time / 1000000 / rate,
memory_usage_kb: result.memory / 1024,
time: result.time / 1000000 / rate,
memory: result.memory / 1024,
files: result.files,
code: result.exitStatus,
};
if (ret.time_usage_ms >= (params.time || 16000)) {
if (ret.time >= (params.time || 16000)) {
ret.status = STATUS.STATUS_TIME_LIMIT_EXCEEDED;
}
ret.files = result.files || {};
+2 -2
View File
@@ -19,7 +19,7 @@ interface Session {
getNext: (task: JudgeTask) => NextFunction;
getEnd: (task: JudgeTask) => NextFunction;
cacheOpen: (source: string, files: any[], next?: NextFunction) => Promise<string>;
fetchCodeFile: (target: string) => Promise<string>;
fetchFile: (target: string) => Promise<string>;
config: { detail: boolean, host?: string };
}
@@ -110,7 +110,7 @@ export class JudgeTask {
if ((this.code as any).content.startsWith('@@hydro_submission_file@@')) {
const id = (this.code as any).content.split('@@hydro_submission_file@@')[1]?.split('#')?.[0];
if (!id) throw new SystemError('Submission File Not Found');
const target = await this.session.fetchCodeFile(id);
const target = await this.session.fetchFile(id);
this.code = { src: target };
this.clean.push(() => fs.remove(target));
}