mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
judge: support binary output (#301)
This commit is contained in:
1 parent
24cd356f78
commit
2c01eaa967
8 files changed
+89
-72
No files matched your search
@@ -11,12 +11,12 @@ const testlibSrc = findFileSync('@hydrooj/hydrojudge/vendor/testlib/testlib.h');
|
|||||||
|
|
||||||
interface CheckConfig {
|
interface CheckConfig {
|
||||||
checker_type: string;
|
checker_type: string;
|
||||||
stdin: string,
|
stdin: CopyInFile,
|
||||||
stdout: string,
|
stdout: CopyInFile,
|
||||||
user_stdout: string,
|
user_stdout: CopyInFile,
|
||||||
user_stderr: string,
|
user_stderr: CopyInFile,
|
||||||
score: number,
|
|
||||||
copyIn?: Record<string, CopyInFile>,
|
copyIn?: Record<string, CopyInFile>,
|
||||||
|
score: number,
|
||||||
detail: boolean,
|
detail: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import { CopyInFile } from './sandbox/interface';
|
|||||||
import { parse } from './testlib';
|
import { parse } from './testlib';
|
||||||
|
|
||||||
interface CheckConfig {
|
interface CheckConfig {
|
||||||
input: string,
|
input: CopyInFile,
|
||||||
output: string,
|
output: CopyInFile,
|
||||||
user_stdout: string,
|
user_stdout: CopyInFile,
|
||||||
user_stderr: string,
|
user_stderr: CopyInFile,
|
||||||
score: number,
|
|
||||||
copyIn: Record<string, CopyInFile>,
|
copyIn: Record<string, CopyInFile>,
|
||||||
|
score: number,
|
||||||
detail: boolean,
|
detail: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@ const checkers: Record<string, Checker> = {
|
|||||||
async default(config) {
|
async default(config) {
|
||||||
const { stdout } = await run('/usr/bin/diff -BZ usrout answer', {
|
const { stdout } = await run('/usr/bin/diff -BZ usrout answer', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
usrout: { src: config.user_stdout },
|
usrout: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -41,22 +41,24 @@ const checkers: Record<string, Checker> = {
|
|||||||
try {
|
try {
|
||||||
const pt = stdout.split('---');
|
const pt = stdout.split('---');
|
||||||
const u = pt[0].split('\n')[1];
|
const u = pt[0].split('\n')[1];
|
||||||
let usr = u.substr(2, u.length - 2).trim().split(' ');
|
const usr = u.substring(2).trim().split(' ');
|
||||||
const t = pt[1].split('\n')[1];
|
const t = pt[1].split('\n')[1];
|
||||||
let std = t.substr(2, t.length - 2).trim().split(' ');
|
const std = t.substring(2).trim().split(' ');
|
||||||
if (usr.length < std.length) message = 'Standard answer longer than user output.';
|
if (usr.length < std.length) message = 'Standard answer longer than user output.';
|
||||||
else if (usr.length > std.length) message = 'User output longer than standard answer.';
|
else if (usr.length > std.length) message = 'User output longer than standard answer.';
|
||||||
else {
|
else {
|
||||||
|
let usrString = usr[0];
|
||||||
|
let stdString = std[0];
|
||||||
for (const i in usr) {
|
for (const i in usr) {
|
||||||
if (usr[i] !== std[i]) {
|
if (usr[i] !== std[i]) {
|
||||||
usr = usr[i];
|
usrString = usr[i];
|
||||||
std = std[i];
|
stdString = std[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (usr.length > 20) usr = `${usr.substring(0, 16)}...`;
|
if (usr.length > 20) usrString = `${usrString.substring(0, 16)}...`;
|
||||||
if (std.length > 20) std = `${std.substring(0, 16)}...`;
|
if (std.length > 20) stdString = `${stdString.substring(0, 16)}...`;
|
||||||
message = { message: 'Read {0}, expect {1}.', params: [usr, std] };
|
message = { message: 'Read {0}, expect {1}.', params: [usrString, stdString] };
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message = stdout.substring(0, stdout.length - 1 <= 30 ? stdout.length - 1 : 30);
|
message = stdout.substring(0, stdout.length - 1 <= 30 ? stdout.length - 1 : 30);
|
||||||
@@ -74,8 +76,8 @@ const checkers: Record<string, Checker> = {
|
|||||||
async strict(config) {
|
async strict(config) {
|
||||||
const { stdout } = await run('/usr/bin/diff usrout answer', {
|
const { stdout } = await run('/usr/bin/diff usrout answer', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
usrout: { src: config.user_stdout },
|
usrout: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -96,9 +98,9 @@ const checkers: Record<string, Checker> = {
|
|||||||
async hustoj(config) {
|
async hustoj(config) {
|
||||||
const { code, stdout } = await run('${dir}/checker input answer usrout', {
|
const { code, stdout } = await run('${dir}/checker input answer usrout', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
usrout: { src: config.user_stdout },
|
usrout: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
input: { src: config.input },
|
input: config.input,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -121,9 +123,9 @@ const checkers: Record<string, Checker> = {
|
|||||||
async lemon(config) {
|
async lemon(config) {
|
||||||
const { files } = await run(`\${dir}/checker input usrout answer ${config.score} score message`, {
|
const { files } = await run(`\${dir}/checker input usrout answer ${config.score} score message`, {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
usrout: { src: config.user_stdout },
|
usrout: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
input: { src: config.input },
|
input: config.input,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
copyOut: ['score', 'message'],
|
copyOut: ['score', 'message'],
|
||||||
@@ -147,8 +149,8 @@ const checkers: Record<string, Checker> = {
|
|||||||
async qduoj(config) {
|
async qduoj(config) {
|
||||||
const { status, stdout } = await run('${dir}/checker input usrout', {
|
const { status, stdout } = await run('${dir}/checker input usrout', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
usrout: { src: config.user_stdout },
|
usrout: config.user_stdout,
|
||||||
input: { src: config.input },
|
input: config.input,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -173,9 +175,9 @@ const checkers: Record<string, Checker> = {
|
|||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
let { status, stdout, stderr } = await run('${dir}/checker', {
|
let { status, stdout, stderr } = await run('${dir}/checker', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
input: { src: config.input },
|
input: config.input,
|
||||||
user_out: { src: config.user_stdout },
|
user_out: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
code: { content: '' },
|
code: { content: '' },
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
@@ -189,9 +191,9 @@ const checkers: Record<string, Checker> = {
|
|||||||
async testlib(config) {
|
async testlib(config) {
|
||||||
const { stderr, status } = await run('${dir}/checker ${dir}/in ${dir}/user_out ${dir}/answer', {
|
const { stderr, status } = await run('${dir}/checker ${dir}/in ${dir}/user_out ${dir}/answer', {
|
||||||
copyIn: {
|
copyIn: {
|
||||||
in: { src: config.input },
|
in: config.input,
|
||||||
user_out: { src: config.user_stdout },
|
user_out: config.user_stdout,
|
||||||
answer: { src: config.output },
|
answer: config.output,
|
||||||
...config.copyIn,
|
...config.copyIn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ import { STATUS } from '@hydrooj/utils/lib/status';
|
|||||||
import { CompileError } from './error';
|
import { CompileError } from './error';
|
||||||
import { Execute } from './interface';
|
import { Execute } from './interface';
|
||||||
import { del, run } from './sandbox';
|
import { del, run } from './sandbox';
|
||||||
|
import { CopyInFile } from './sandbox/interface';
|
||||||
import { compilerText } from './utils';
|
import { compilerText } from './utils';
|
||||||
|
|
||||||
export = async function compile(
|
export = async function compile(
|
||||||
lang: LangConfig, code: string, target: string, copyIn: any = {}, next?: Function,
|
lang: LangConfig, code: string, target: string, copyIn: Record<string, CopyInFile> = {}, next?: Function,
|
||||||
): Promise<Execute> {
|
): Promise<Execute> {
|
||||||
target = lang.target || target;
|
target = lang.target || target;
|
||||||
copyIn[lang.code_file] = { content: code };
|
copyIn[lang.code_file] = { content: code };
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ export interface Execute {
|
|||||||
export interface CompileErrorInfo {
|
export interface CompileErrorInfo {
|
||||||
stdout?: string,
|
stdout?: string,
|
||||||
stderr?: string,
|
stderr?: string,
|
||||||
status?: string
|
status?: number
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import path from 'path';
|
|
||||||
import fs from 'fs-extra';
|
|
||||||
import Queue from 'p-queue';
|
import Queue from 'p-queue';
|
||||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||||
import { check, compileChecker } from '../check';
|
import { check, compileChecker } from '../check';
|
||||||
import compile from '../compile';
|
import compile from '../compile';
|
||||||
import { getConfig } from '../config';
|
import { getConfig } from '../config';
|
||||||
import { CompileError, FormatError } from '../error';
|
import { CompileError, FormatError } from '../error';
|
||||||
import { run } from '../sandbox';
|
import { del, run } from '../sandbox';
|
||||||
import signals from '../signals';
|
import signals from '../signals';
|
||||||
import { parseFilename } from '../utils';
|
import { parseFilename } from '../utils';
|
||||||
import {
|
import {
|
||||||
@@ -40,26 +38,25 @@ function judgeCase(c: Case, sid: string) {
|
|||||||
const { filename } = ctx.config;
|
const { filename } = ctx.config;
|
||||||
const copyIn = { ...ctx.execute.copyIn };
|
const copyIn = { ...ctx.execute.copyIn };
|
||||||
if (filename) copyIn[`${filename}.in`] = c.input ? { src: c.input } : { content: '' };
|
if (filename) copyIn[`${filename}.in`] = c.input ? { src: c.input } : { content: '' };
|
||||||
const copyOut = filename ? [`${filename}.out?`] : [];
|
const copyOutCached = filename ? [`${filename}.out?`] : [];
|
||||||
const stdin = filename ? null : c.input;
|
const stdin = filename ? null : c.input;
|
||||||
const stdout = path.resolve(ctx.tmpdir, `${c.id}.out`);
|
|
||||||
const stderr = path.resolve(ctx.tmpdir, `${c.id}.err`);
|
|
||||||
const res = await run(
|
const res = await run(
|
||||||
ctx.execute.execute.replace(/\$\{name\}/g, 'code'),
|
ctx.execute.execute.replace(/\$\{name\}/g, 'code'),
|
||||||
{
|
{
|
||||||
stdin,
|
stdin,
|
||||||
stdout: filename ? null : stdout,
|
|
||||||
stderr,
|
|
||||||
copyIn,
|
copyIn,
|
||||||
copyOut,
|
copyOutCached,
|
||||||
time: ctxSubtask.subtask.time * ctx.execute.time,
|
time: ctxSubtask.subtask.time * ctx.execute.time,
|
||||||
memory: ctxSubtask.subtask.memory,
|
memory: ctxSubtask.subtask.memory,
|
||||||
|
cacheStdoutAndStderr: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { code, time_usage_ms, memory_usage_kb } = res;
|
const { code, time_usage_ms, memory_usage_kb } = res;
|
||||||
let { status } = res;
|
let { status } = res;
|
||||||
if (res.files[`${filename}.out`] || !fs.existsSync(stdout)) {
|
let stdout = { fileId: res.fileIds['stdout'] };
|
||||||
fs.writeFileSync(stdout, res.files[`${filename}.out`] || '');
|
const stderr = { fileId: res.fileIds['stderr'] };
|
||||||
|
if (res.fileIds[`${filename}.out`]) {
|
||||||
|
stdout = { fileId: res.fileIds[`${filename}.out`] };
|
||||||
}
|
}
|
||||||
let message: any = '';
|
let message: any = '';
|
||||||
let score = 0;
|
let score = 0;
|
||||||
@@ -71,8 +68,8 @@ function judgeCase(c: Case, sid: string) {
|
|||||||
} else {
|
} else {
|
||||||
[status, score, message] = await check({
|
[status, score, message] = await check({
|
||||||
copyIn: ctx.checker.copyIn,
|
copyIn: ctx.checker.copyIn,
|
||||||
stdin: c.input,
|
stdin: { src: c.input },
|
||||||
stdout: c.output,
|
stdout: { src: c.output },
|
||||||
user_stdout: stdout,
|
user_stdout: stdout,
|
||||||
user_stderr: stderr,
|
user_stderr: stderr,
|
||||||
checker_type: ctx.config.checker_type,
|
checker_type: ctx.config.checker_type,
|
||||||
@@ -84,10 +81,9 @@ function judgeCase(c: Case, sid: string) {
|
|||||||
if (code < 32) message = signals[code];
|
if (code < 32) message = signals[code];
|
||||||
else message = { message: 'Your program returned {0}.', params: [code] };
|
else message = { message: 'Your program returned {0}.', params: [code] };
|
||||||
}
|
}
|
||||||
await Promise.all([
|
await Promise.all(
|
||||||
fs.remove(stdout),
|
Object.values(res.fileIds).map((id) => del(id)),
|
||||||
fs.remove(stderr),
|
).catch(() => { /* Ignore file doesn't exist */ });
|
||||||
]).catch(() => { /* Ignore file doesn't exist */ });
|
|
||||||
if (runner && ctx.rerun && status === STATUS.STATUS_TIME_LIMIT_EXCEEDED) {
|
if (runner && ctx.rerun && status === STATUS.STATUS_TIME_LIMIT_EXCEEDED) {
|
||||||
ctx.rerun--;
|
ctx.rerun--;
|
||||||
await runner(ctx, ctxSubtask);
|
await runner(ctx, ctxSubtask);
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ export const judge = async (ctx: Context) => {
|
|||||||
} else {
|
} else {
|
||||||
[status, , message] = await check({
|
[status, , message] = await check({
|
||||||
copyIn: copyInDir(path.resolve(ctx.tmpdir, 'checker')),
|
copyIn: copyInDir(path.resolve(ctx.tmpdir, 'checker')),
|
||||||
stdin: input,
|
stdin: { src: input },
|
||||||
stdout,
|
stdout: { src: stdout },
|
||||||
user_stdout: stdout,
|
user_stdout: { src: stdout },
|
||||||
user_stderr: stderr,
|
user_stderr: { src: stderr },
|
||||||
checker_type: ctx.config.checker_type,
|
checker_type: ctx.config.checker_type,
|
||||||
score: 100,
|
score: 100,
|
||||||
detail: ctx.config.detail,
|
detail: ctx.config.detail,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Queue from 'p-queue';
|
|||||||
import { STATUS } from '@hydrooj/utils/lib/status';
|
import { STATUS } from '@hydrooj/utils/lib/status';
|
||||||
import compile from '../compile';
|
import compile from '../compile';
|
||||||
import { getConfig } from '../config';
|
import { getConfig } from '../config';
|
||||||
import { run } from '../sandbox';
|
import { runPiped } from '../sandbox';
|
||||||
import signals from '../signals';
|
import signals from '../signals';
|
||||||
import { parse } from '../testlib';
|
import { parse } from '../testlib';
|
||||||
import { findFileSync, parseFilename } from '../utils';
|
import { findFileSync, parseFilename } from '../utils';
|
||||||
@@ -22,20 +22,21 @@ function judgeCase(c: Case) {
|
|||||||
return async (ctx: Context, ctxSubtask: ContextSubTask) => {
|
return async (ctx: Context, ctxSubtask: ContextSubTask) => {
|
||||||
ctx.executeInteractor.copyIn.in = c.input ? { src: c.input } : { content: '' };
|
ctx.executeInteractor.copyIn.in = c.input ? { src: c.input } : { content: '' };
|
||||||
ctx.executeInteractor.copyIn.out = c.output ? { src: c.output } : { content: '' };
|
ctx.executeInteractor.copyIn.out = c.output ? { src: c.output } : { content: '' };
|
||||||
const [{ code, time_usage_ms, memory_usage_kb }, resInteractor] = await run([
|
const [{ code, time_usage_ms, memory_usage_kb }, resInteractor] = await runPiped(
|
||||||
{
|
{
|
||||||
execute: ctx.executeUser.execute.replace(/\$\{name\}/g, 'code'),
|
execute: ctx.executeUser.execute.replace(/\$\{name\}/g, 'code'),
|
||||||
copyIn: ctx.executeUser.copyIn,
|
copyIn: ctx.executeUser.copyIn,
|
||||||
time: ctxSubtask.subtask.time * ctx.executeUser.time,
|
time: ctxSubtask.subtask.time * ctx.executeUser.time,
|
||||||
memory: ctxSubtask.subtask.memory,
|
memory: ctxSubtask.subtask.memory,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
execute: `${ctx.executeInteractor.execute.replace(/\$\{name\}/g, 'interactor')} /w/in /w/tout /w/out`,
|
execute: `${ctx.executeInteractor.execute.replace(/\$\{name\}/g, 'interactor')} /w/in /w/tout /w/out`,
|
||||||
copyIn: ctx.executeInteractor.copyIn,
|
copyIn: ctx.executeInteractor.copyIn,
|
||||||
time: ctxSubtask.subtask.time * 2 * ctx.executeInteractor.time,
|
time: ctxSubtask.subtask.time * 2 * ctx.executeInteractor.time,
|
||||||
memory: ctxSubtask.subtask.memory * 2,
|
memory: ctxSubtask.subtask.memory * 2,
|
||||||
copyOut: ['/w/tout?'],
|
copyOut: ['/w/tout?'],
|
||||||
},
|
},
|
||||||
]);
|
);
|
||||||
// TODO handle tout (maybe pass to checker?)
|
// TODO handle tout (maybe pass to checker?)
|
||||||
let status: number;
|
let status: number;
|
||||||
let score = 0;
|
let score = 0;
|
||||||
|
|||||||
@@ -38,6 +38,19 @@ interface Parameter {
|
|||||||
copyIn?: Record<string, CopyInFile>;
|
copyIn?: Record<string, CopyInFile>;
|
||||||
copyOut?: string[];
|
copyOut?: string[];
|
||||||
copyOutCached?: string[];
|
copyOutCached?: string[];
|
||||||
|
cacheStdoutAndStderr?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SandboxAdaptedResult {
|
||||||
|
status: number;
|
||||||
|
code: number;
|
||||||
|
time_usage_ms: number;
|
||||||
|
memory_usage_kb?: number;
|
||||||
|
files: Record<string, string>;
|
||||||
|
fileIds?: Record<string, string>;
|
||||||
|
stdout?: string;
|
||||||
|
stderr?: string;
|
||||||
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkStringArray(args: ParseEntry[]): args is string[] {
|
function checkStringArray(args: ParseEntry[]): args is string[] {
|
||||||
@@ -58,12 +71,17 @@ function proc({
|
|||||||
memory = parseMemoryMB(getConfig('memoryMax')),
|
memory = parseMemoryMB(getConfig('memoryMax')),
|
||||||
processLimit = getConfig('processLimit'),
|
processLimit = getConfig('processLimit'),
|
||||||
stdin = '', copyIn = {}, copyOut = [], copyOutCached = [],
|
stdin = '', copyIn = {}, copyOut = [], copyOutCached = [],
|
||||||
|
cacheStdoutAndStderr = false,
|
||||||
}: Parameter = {}): Cmd {
|
}: Parameter = {}): Cmd {
|
||||||
if (!supportOptional) {
|
if (!supportOptional) {
|
||||||
copyOut = (copyOut as string[]).map((i) => (i.endsWith('?') ? i.substr(0, i.length - 1) : i));
|
copyOut = (copyOut as string[]).map((i) => (i.endsWith('?') ? i.substr(0, i.length - 1) : i));
|
||||||
}
|
}
|
||||||
const size = parseMemoryMB(getConfig('stdio_size'));
|
const size = parseMemoryMB(getConfig('stdio_size'));
|
||||||
const rate = getConfig('rate');
|
const rate = getConfig('rate');
|
||||||
|
const copyOutCachedCopy = [...copyOutCached];
|
||||||
|
if (cacheStdoutAndStderr) {
|
||||||
|
copyOutCachedCopy.push('stdout', 'stderr');
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
args: parseArgs(execute),
|
args: parseArgs(execute),
|
||||||
env: getConfig('env').split('\n'),
|
env: getConfig('env').split('\n'),
|
||||||
@@ -80,14 +98,14 @@ function proc({
|
|||||||
procLimit: processLimit,
|
procLimit: processLimit,
|
||||||
copyIn,
|
copyIn,
|
||||||
copyOut,
|
copyOut,
|
||||||
copyOutCached,
|
copyOutCached: copyOutCachedCopy,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function adaptResult(result: SandboxResult, params: Parameter) {
|
async function adaptResult(result: SandboxResult, params: Parameter): Promise<SandboxAdaptedResult> {
|
||||||
const rate = getConfig('rate');
|
const rate = getConfig('rate') as number;
|
||||||
// FIXME: Signalled?
|
// FIXME: Signalled?
|
||||||
const ret: any = {
|
const ret: SandboxAdaptedResult = {
|
||||||
status: statusMap.get(result.status) || STATUS.STATUS_ACCEPTED,
|
status: statusMap.get(result.status) || STATUS.STATUS_ACCEPTED,
|
||||||
time_usage_ms: result.time / 1000000 / rate,
|
time_usage_ms: result.time / 1000000 / rate,
|
||||||
memory_usage_kb: result.memory / 1024,
|
memory_usage_kb: result.memory / 1024,
|
||||||
@@ -107,14 +125,14 @@ async function adaptResult(result: SandboxResult, params: Parameter) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runMultiple(execute: Parameter[]) {
|
export async function runPiped(execute0: Parameter, execute1: Parameter): Promise<[SandboxAdaptedResult, SandboxAdaptedResult]> {
|
||||||
let res: SandboxResult[];
|
let res: SandboxResult[];
|
||||||
const size = parseMemoryMB(getConfig('stdio_size'));
|
const size = parseMemoryMB(getConfig('stdio_size'));
|
||||||
try {
|
try {
|
||||||
const body = {
|
const body = {
|
||||||
cmd: [
|
cmd: [
|
||||||
proc(execute[0]),
|
proc(execute0),
|
||||||
proc(execute[1]),
|
proc(execute1),
|
||||||
],
|
],
|
||||||
pipeMapping: [{
|
pipeMapping: [{
|
||||||
in: { index: 0, fd: 1 },
|
in: { index: 0, fd: 1 },
|
||||||
@@ -142,16 +160,15 @@ export async function runMultiple(execute: Parameter[]) {
|
|||||||
if (e instanceof FormatError) throw e;
|
if (e instanceof FormatError) throw e;
|
||||||
throw new SystemError('Sandbox Error', [e]);
|
throw new SystemError('Sandbox Error', [e]);
|
||||||
}
|
}
|
||||||
return await Promise.all(res.map((r) => adaptResult(r, {})));
|
return await Promise.all(res.map((r) => adaptResult(r, {}))) as [SandboxAdaptedResult, SandboxAdaptedResult];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function del(fileId: string) {
|
export async function del(fileId: string) {
|
||||||
await new SandboxClient(getConfig('sandbox_host')).deleteFile(fileId);
|
await new SandboxClient(getConfig('sandbox_host')).deleteFile(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function run(execute: string | Parameter[], params?: Parameter) {
|
export async function run(execute: string, params?: Parameter): Promise<SandboxAdaptedResult> {
|
||||||
let result: SandboxResult;
|
let result: SandboxResult;
|
||||||
if (typeof execute === 'object') return await runMultiple(execute);
|
|
||||||
try {
|
try {
|
||||||
const client = new SandboxClient(getConfig('sandbox_host'));
|
const client = new SandboxClient(getConfig('sandbox_host'));
|
||||||
if (!supportOptional) {
|
if (!supportOptional) {
|
||||||
|
|||||||
Reference in new issue
Block a user