From 7f967060cd2cf995a7cd4508788a384b25268152 Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 30 Aug 2022 22:26:46 +0800 Subject: [PATCH] judge: remove useless suffix --- packages/hydrojudge/src/checkers.ts | 17 ++++++++++++++--- packages/hydrojudge/src/flow.ts | 8 ++++---- packages/hydrojudge/src/hosts/builtin.ts | 2 +- packages/hydrojudge/src/hosts/hydro.ts | 2 +- packages/hydrojudge/src/interface.ts | 12 ------------ packages/hydrojudge/src/judge/default.ts | 18 +++++++++--------- packages/hydrojudge/src/judge/interactive.ts | 14 +++++++------- packages/hydrojudge/src/judge/interface.ts | 4 ++-- packages/hydrojudge/src/judge/run.ts | 20 +++++++++----------- packages/hydrojudge/src/sandbox.ts | 18 ++++++++++-------- packages/hydrojudge/src/task.ts | 4 ++-- packages/hydrooj/src/interface.ts | 2 ++ 12 files changed, 61 insertions(+), 60 deletions(-) diff --git a/packages/hydrojudge/src/checkers.ts b/packages/hydrojudge/src/checkers.ts index 9cb9a3c24..50734b9b8 100644 --- a/packages/hydrojudge/src/checkers.ts +++ b/packages/hydrojudge/src/checkers.ts @@ -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; + score: number; + detail: boolean; + env?: Record; +} + type Checker = (config: CheckConfig) => Promise<{ status: number, score: number, @@ -202,4 +213,4 @@ const checkers: Record = new Proxy({ }, }); -export = checkers; +export default checkers; diff --git a/packages/hydrojudge/src/flow.ts b/packages/hydrojudge/src/flow.ts index aa58bdce8..6cbc2ab46 100644 --- a/packages/hydrojudge/src/flow.ts +++ b/packages/hydrojudge/src/flow.ts @@ -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, }); }; diff --git a/packages/hydrojudge/src/hosts/builtin.ts b/packages/hydrojudge/src/hosts/builtin.ts index 2201ab91c..c156aa40f 100644 --- a/packages/hydrojudge/src/hosts/builtin.ts +++ b/packages/hydrojudge/src/hosts/builtin.ts @@ -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; diff --git a/packages/hydrojudge/src/hosts/hydro.ts b/packages/hydrojudge/src/hosts/hydro.ts index 78b0b8723..f872ed90e 100644 --- a/packages/hydrojudge/src/hosts/hydro.ts +++ b/packages/hydrojudge/src/hosts/hydro.ts @@ -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}`)); diff --git a/packages/hydrojudge/src/interface.ts b/packages/hydrojudge/src/interface.ts index a9f4ce2b4..31ee95dee 100644 --- a/packages/hydrojudge/src/interface.ts +++ b/packages/hydrojudge/src/interface.ts @@ -6,15 +6,3 @@ export interface Execute { copyIn: Record; time?: number; } - -export interface CheckConfig { - execute: string; - input: CopyInFile; - output: CopyInFile; - user_stdout: CopyInFile; - user_stderr: CopyInFile; - copyIn: Record; - score: number; - detail: boolean; - env?: Record; -} diff --git a/packages/hydrojudge/src/judge/default.ts b/packages/hydrojudge/src/judge/default.ts index e570b643e..d9b2dca2f 100644 --- a/packages/hydrojudge/src/judge/default.ts +++ b/packages/hydrojudge/src/judge/default.ts @@ -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 || '' }, diff --git a/packages/hydrojudge/src/judge/interactive.ts b/packages/hydrojudge/src/judge/interactive.ts index 9af8dd2a8..73c06d1f2 100644 --- a/packages/hydrojudge/src/judge/interactive.ts +++ b/packages/hydrojudge/src/judge/interactive.ts @@ -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, diff --git a/packages/hydrojudge/src/judge/interface.ts b/packages/hydrojudge/src/judge/interface.ts index 939430d56..74f79a2ba 100644 --- a/packages/hydrojudge/src/judge/interface.ts +++ b/packages/hydrojudge/src/judge/interface.ts @@ -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; diff --git a/packages/hydrojudge/src/judge/run.ts b/packages/hydrojudge/src/judge/run.ts index 54087444f..c3a973e84 100644 --- a/packages/hydrojudge/src/judge/run.ts +++ b/packages/hydrojudge/src/judge/run.ts @@ -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, }); }; diff --git a/packages/hydrojudge/src/sandbox.ts b/packages/hydrojudge/src/sandbox.ts index d0eac3f44..8fe93a67d 100644 --- a/packages/hydrojudge/src/sandbox.ts +++ b/packages/hydrojudge/src/sandbox.ts @@ -30,7 +30,7 @@ const statusMap: Map = 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; fileIds?: Record; 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= (params.time || 16000)) { + if (ret.time >= (params.time || 16000)) { ret.status = STATUS.STATUS_TIME_LIMIT_EXCEEDED; } ret.files = result.files || {}; diff --git a/packages/hydrojudge/src/task.ts b/packages/hydrojudge/src/task.ts index cc6128e95..7851629ad 100644 --- a/packages/hydrojudge/src/task.ts +++ b/packages/hydrojudge/src/task.ts @@ -19,7 +19,7 @@ interface Session { getNext: (task: JudgeTask) => NextFunction; getEnd: (task: JudgeTask) => NextFunction; cacheOpen: (source: string, files: any[], next?: NextFunction) => Promise; - fetchCodeFile: (target: string) => Promise; + fetchFile: (target: string) => Promise; 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)); } diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 7bda7d316..891191cd8 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -514,7 +514,9 @@ export interface JudgeResultBody { case?: TestCase, status?: number; score?: number; + /** in miliseconds */ time?: number; + /** in kilobytes */ memory?: number; message?: string | JudgeMessage; compilerText?: string;