mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
judge: remove check() function
This commit is contained in:
1 parent
1c6cdfc6ff
commit
805c8e4cd3
6 files changed
+43
-53
No files matched your search
@@ -1,35 +0,0 @@
|
||||
import { findFileSync } from '@hydrooj/utils/lib/utils';
|
||||
import checkers from './checkers';
|
||||
import compile from './compile';
|
||||
import { SystemError } from './error';
|
||||
import { CheckConfig, Execute } from './interface';
|
||||
|
||||
const testlibSrc = findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h');
|
||||
|
||||
export async function check(config: CheckConfig): Promise<[number, number, string]> {
|
||||
if (!checkers[config.checker_type]) throw new SystemError('Unknown checker type {0}', [config.checker_type]);
|
||||
const {
|
||||
code, status, score, message,
|
||||
} = await checkers[config.checker_type](config);
|
||||
if (code) throw new SystemError('Checker returned {0}.', [code]);
|
||||
return [status, score, message];
|
||||
}
|
||||
|
||||
export async function compileChecker(getLang: Function, checkerType: string, checker: string, copyIn: any): Promise<Execute> {
|
||||
if (['default', 'strict'].includes(checkerType)) {
|
||||
return { execute: '', copyIn: {}, clean: () => Promise.resolve(null) };
|
||||
}
|
||||
if (!checkers[checkerType]) throw new SystemError('Unknown checker type {0}.', [checkerType]);
|
||||
if (checkerType === 'testlib') copyIn['testlib.h'] = { src: testlibSrc };
|
||||
const s = checker.replace('@', '.').split('.');
|
||||
let lang;
|
||||
let langId = s.pop();
|
||||
while (s.length) {
|
||||
lang = getLang(langId, false);
|
||||
if (lang) break;
|
||||
langId = `${s.pop()}.${langId}`;
|
||||
}
|
||||
if (!lang) throw new SystemError('Unknown checker language.');
|
||||
// TODO cache compiled checker
|
||||
return await compile(lang, { src: checker }, copyIn);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||
import { SystemError } from './error';
|
||||
import { FormatError, SystemError } from './error';
|
||||
import { CheckConfig } from './interface';
|
||||
import { run } from './sandbox';
|
||||
import { parse } from './testlib';
|
||||
@@ -9,10 +9,9 @@ type Checker = (config: CheckConfig) => Promise<{
|
||||
status: number,
|
||||
score: number,
|
||||
message: string,
|
||||
code?: number,
|
||||
}>;
|
||||
|
||||
const checkers: Record<string, Checker> = {
|
||||
const checkers: Record<string, Checker> = new Proxy({
|
||||
async default(config) {
|
||||
const { stdout } = await run('/usr/bin/diff -BZ usrout answer', {
|
||||
copyIn: {
|
||||
@@ -196,6 +195,11 @@ const checkers: Record<string, Checker> = {
|
||||
}
|
||||
return parse(stderr, config.score);
|
||||
},
|
||||
};
|
||||
}, {
|
||||
get(self, key) {
|
||||
if (!self[key]) throw new FormatError('Unknown checker type {0}', [key]);
|
||||
return self[key];
|
||||
},
|
||||
});
|
||||
|
||||
export = checkers;
|
||||
@@ -1,11 +1,13 @@
|
||||
import { LangConfig } from '@hydrooj/utils/lib/lang';
|
||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||
import { CompileError } from './error';
|
||||
import { findFileSync } from '@hydrooj/utils/lib/utils';
|
||||
import checkers from './checkers';
|
||||
import { CompileError, FormatError } from './error';
|
||||
import { Execute } from './interface';
|
||||
import { CopyInFile, del, run } from './sandbox';
|
||||
import { compilerText } from './utils';
|
||||
|
||||
export = async function compile(
|
||||
export default async function compile(
|
||||
lang: LangConfig, code: CopyInFile, copyIn: Record<string, CopyInFile> = {}, next?: Function,
|
||||
): Promise<Execute> {
|
||||
const target = lang.target || 'foo';
|
||||
@@ -24,7 +26,7 @@ export = async function compile(
|
||||
);
|
||||
if (status !== STATUS.STATUS_ACCEPTED) throw new CompileError({ status, stdout, stderr });
|
||||
if (!fileIds[target]) throw new CompileError({ stderr: 'Executable file not found.' });
|
||||
if (next) next({ compilerText: compilerText(stdout, stderr) });
|
||||
next?.({ compilerText: compilerText(stdout, stderr) });
|
||||
return {
|
||||
execute,
|
||||
copyIn: { ...copyIn, [target]: { fileId: fileIds[target] } },
|
||||
@@ -38,4 +40,25 @@ export = async function compile(
|
||||
clean: () => Promise.resolve(null),
|
||||
time,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const testlibSrc = findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h');
|
||||
|
||||
export async function compileChecker(getLang: Function, checkerType: string, checker: string, copyIn: any): Promise<Execute> {
|
||||
if (['default', 'strict'].includes(checkerType)) {
|
||||
return { execute: '', copyIn: {}, clean: () => Promise.resolve(null) };
|
||||
}
|
||||
if (!checkers[checkerType]) throw new FormatError('Unknown checker type {0}.', [checkerType]);
|
||||
if (checkerType === 'testlib') copyIn['testlib.h'] = { src: testlibSrc };
|
||||
const s = checker.replace('@', '.').split('.');
|
||||
let lang;
|
||||
let langId = s.pop();
|
||||
while (s.length) {
|
||||
lang = getLang(langId, false);
|
||||
if (lang) break;
|
||||
langId = `${s.pop()}.${langId}`;
|
||||
}
|
||||
if (!lang) throw new FormatError('Unknown checker language.');
|
||||
// TODO cache compiled checker
|
||||
return await compile(lang, { src: checker }, copyIn);
|
||||
}
|
||||
@@ -9,7 +9,6 @@ export interface Execute {
|
||||
|
||||
export interface CheckConfig {
|
||||
execute: string;
|
||||
checker_type: string;
|
||||
input: CopyInFile;
|
||||
output: CopyInFile;
|
||||
user_stdout: CopyInFile;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { basename } from 'path';
|
||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||
import { check, compileChecker } from '../check';
|
||||
import compile from '../compile';
|
||||
import checkers from '../checkers';
|
||||
import compile, { compileChecker } from '../compile';
|
||||
import { runFlow } from '../flow';
|
||||
import { Logger } from '../log';
|
||||
import { CmdFile, del, run } from '../sandbox';
|
||||
@@ -48,18 +48,17 @@ function judgeCase(c: NormalizedCase, sid: string) {
|
||||
} else if (memory_usage_kb > c.memory * 1024) {
|
||||
status = STATUS.STATUS_MEMORY_LIMIT_EXCEEDED;
|
||||
} else {
|
||||
[status, score, message] = await check({
|
||||
({ status, score, message } = await checkers[ctx.config.checker_type]({
|
||||
execute: ctx.checker.execute,
|
||||
copyIn: ctx.checker.copyIn || {},
|
||||
input: { src: c.input },
|
||||
output: { src: c.output },
|
||||
user_stdout: stdout,
|
||||
user_stderr: stderr,
|
||||
checker_type: ctx.config.checker_type,
|
||||
score: c.score,
|
||||
detail: ctx.config.detail ?? true,
|
||||
env: { ...ctx.env, HYDRO_TESTCASE: c.id.toString() },
|
||||
});
|
||||
}));
|
||||
}
|
||||
} else if (status === STATUS.STATUS_RUNTIME_ERROR && code) {
|
||||
if (code < 32) message = signals[code];
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { basename } from 'path';
|
||||
import { readFile } from 'fs-extra';
|
||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||
import { check, compileChecker } from '../check';
|
||||
import checkers from '../checkers';
|
||||
import { compileChecker } from '../compile';
|
||||
import { runFlow } from '../flow';
|
||||
import { del, run } from '../sandbox';
|
||||
import { NormalizedCase } from '../utils';
|
||||
@@ -47,18 +48,17 @@ function judgeCase(c: NormalizedCase, sid: string) {
|
||||
fileIds.push(...Object.values(res.fileIds));
|
||||
}
|
||||
if (status === STATUS.STATUS_ACCEPTED) {
|
||||
[status, score, message] = await check({
|
||||
({ status, score, message } = await checkers[ctx.config.checker_type]({
|
||||
execute: ctx.checker.execute,
|
||||
copyIn: ctx.checker.copyIn || {},
|
||||
input: { src: c.input },
|
||||
output: { src: c.output },
|
||||
user_stdout: file,
|
||||
user_stderr: { content: '' },
|
||||
checker_type: ctx.config.checker_type,
|
||||
score: c.score,
|
||||
detail: ctx.config.detail ?? true,
|
||||
env: { ...ctx.env, HYDRO_TESTCASE: c.id.toString() },
|
||||
});
|
||||
}));
|
||||
}
|
||||
await Promise.all(fileIds.map(del)).catch(() => { /* Ignore file doesn't exist */ });
|
||||
ctxSubtask.score = Score[ctxSubtask.subtask.type](ctxSubtask.score, score);
|
||||
|
||||
Reference in new issue
Block a user