修复分数为0时不会自动更新成绩的问题,添加旧版测试数据格式兼容

This commit is contained in:
undefined committed 2020-09-26 23:30:46 +08:00
1 parent e1cfe1cf4d
commit 441515297a
7 files changed
+69 -31

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/hydrojudge",
"version": "2.0.12",
"version": "2.0.13",
"main": "package.json",
"author": "masnn",
"os": [
+42 -4
View File
@@ -4,7 +4,17 @@ import { Dictionary } from 'lodash';
import { FormatError, SystemError } from './error';
import { parseTimeMS, parseMemoryMB, ensureFile } from './utils';
const RE0 = [
interface Re0 {
reg: RegExp,
output: (a: RegExpExecArray) => string,
id: (a: RegExpExecArray) => number,
}
interface Re1 extends Re0 {
subtask: (a: RegExpExecArray) => number,
}
const RE0: Re0[] = [
{
reg: /^([a-z+_\-A-Z]*)([0-9]+).in$/,
output: (a) => `${a[1] + a[2]}.out`,
@@ -25,8 +35,28 @@ const RE0 = [
output: (a) => `output${a[2]}.txt`,
id: (a) => parseInt(a[2], 10),
},
{
reg: /^input\/([a-z+_\-A-Z]*)([0-9]+).in$/,
output: (a) => `output/${a[1] + a[2]}.out`,
id: (a) => parseInt(a[2], 10),
},
{
reg: /^input\/([a-z+_\-A-Z]*)([0-9]+).in$/,
output: (a) => `output/${a[1] + a[2]}.ans`,
id: (a) => parseInt(a[2], 10),
},
{
reg: /^input\/([a-z+_\-A-Z0-9]*)\.in([0-9]+)$/,
output: (a) => `output/${a[1]}.ou${a[2]}`,
id: (a) => parseInt(a[2], 10),
},
{
reg: /^input\/(input)([0-9]+).txt$/,
output: (a) => `output/output${a[2]}.txt`,
id: (a) => parseInt(a[2], 10),
},
];
const RE1 = [
const RE1: Re1[] = [
{
reg: /^([a-z+_\-A-Z]*)([0-9]+)-([0-9]+).in$/,
output: (a) => `${a[1] + a[2]}-${a[3]}.out`,
@@ -35,7 +65,7 @@ const RE1 = [
},
];
async function read0(folder, files, checkFile) {
async function read0(folder: string, files: string[], checkFile) {
const cases = [];
for (const file of files) {
for (const REG of RE0) {
@@ -89,7 +119,7 @@ async function read0(folder, files, checkFile) {
return config;
}
async function read1(folder, files, checkFile) {
async function read1(folder: string, files: string[], checkFile) {
const subtask = {};
const subtasks = [];
for (const file of files) {
@@ -144,6 +174,14 @@ async function readAutoCases(folder, { next }) {
const checkFile = ensureFile(folder);
try {
const files = await fs.readdir(folder);
if (await fs.pathExists(path.resolve(folder, 'input'))) {
const inputs = await fs.readdir(path.resolve(folder, 'input'));
files.push(...inputs.map((i) => `input/${i}`));
}
if (await fs.pathExists(path.resolve(folder, 'output'))) {
const outputs = await fs.readdir(path.resolve(folder, 'output'));
files.push(...outputs.map((i) => `output/${i}`));
}
let result = await read0(folder, files, checkFile);
if (!result.count) result = await read1(folder, files, checkFile);
Object.assign(config, result);
+2 -1
View File
@@ -3,7 +3,7 @@ import path from 'path';
import fs from 'fs-extra';
import { argv } from 'yargs';
import { STATUS } from 'hydrooj/dist/model/builtin';
import { CompileError } from '../error';
import { CompileError, SystemError } from '../error';
import { copyInDir, parseFilename } from '../utils';
import { run } from '../sandbox';
import compile from '../compile';
@@ -106,6 +106,7 @@ function judgeSubtask(subtask) {
}
export const judge = async (ctx) => {
if (!ctx.config.subtasks.length) throw new SystemError('没有找到测试数据');
if (ctx.config.template) {
if (ctx.config.template[ctx.lang]) {
const tpl = ctx.config.template[ctx.lang];
+12 -14
View File
@@ -28,6 +28,8 @@ async function postInit() {
const { problem, file, task } = global.Hydro.model;
const _judge = global.Hydro.handler.judge as any;
const { monitor } = global.Hydro.service;
const { Logger } = global.Hydro.Logger;
const logger = new Logger('judge');
const info = await sysinfo.get();
monitor.updateJudger(info);
@@ -85,7 +87,7 @@ async function postInit() {
async function cacheOpen(domainId: string, pid: string, version: string) {
const filePath = path.join(homedir(), '.cache', 'hydro', 'judge', domainId, pid);
console.log(filePath);
logger.debug('Cache found at %s', filePath);
if (fs.existsSync(filePath)) {
let ver: string;
try {
@@ -103,7 +105,8 @@ async function postInit() {
function getNext(that) {
that.nextId = 1;
that.nextWaiting = [];
return (data, id) => {
return (data, id = 0) => {
logger.debug('Next: %d %o', id, data);
data.domainId = that.domainId;
data.rid = new ObjectID(that.rid);
data.time = data.time_ms || data.time;
@@ -143,14 +146,9 @@ async function postInit() {
data.key = 'end';
data.rid = new ObjectID(rid);
data.domainId = domainId;
data.time = data.time_ms || data.time;
data.memory = data.memory_kb || data.memory;
console.log({
status: data.status,
score: data.score,
time_ms: data.time_ms,
memory_kb: data.memory_kb,
});
data.time = data.time_ms ?? data.time;
data.memory = data.memory_kb ?? data.memory;
logger.info('End: status=%d score=%d time=%dms memory=%dkb', data.status, data.score, data.time, data.memory);
_judge.end(data);
};
}
@@ -176,7 +174,7 @@ async function postInit() {
config: any;
next: (data: any, id?: any) => void;
next: (data: any, id?: number) => void;
end: (data: any) => void;
@@ -208,7 +206,7 @@ async function postInit() {
this.clean = [];
fs.ensureDirSync(this.tmpdir);
tmpfs.mount(this.tmpdir, '64m');
console.log(`Submission: ${this.rid}`, { pid: this.pid });
logger.info(`Submission: ${this.rid}`, { pid: this.pid });
if (this.config.input) await this.run();
else if (this.config.hack) await this.hack();
else await this.submission();
@@ -224,7 +222,7 @@ async function postInit() {
status: STATUS_SYSTEM_ERROR, score: 0, time_ms: 0, memory_kb: 0,
});
} else {
console.error(e);
logger.error(e);
this.next({ message: `${e.message}\n${e.stack}\n${JSON.stringify(e.params)}` });
this.end({
status: STATUS_SYSTEM_ERROR, score: 0, time_ms: 0, memory_kb: 0,
@@ -269,7 +267,7 @@ async function postInit() {
}
}
task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(console.error));
task.consume({ type: 'judge' }, (t) => (new JudgeTask(t)).handle().catch(logger.error));
}
global.Hydro.service.bus.once('app/started', postInit);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.13.20",
"version": "2.13.21",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
+8 -8
View File
@@ -57,10 +57,10 @@ export async function next(body: JudgeResultBody) {
$push.compilerTexts = body.compilerText;
}
if (body.status) $set.status = body.status;
if (body.score) $set.score = body.score;
if (body.time) $set.time = body.time;
if (body.memory) $set.memory = body.memory;
if (body.progress) $set.progress = body.progress;
if (body.score !== undefined) $set.score = body.score;
if (body.time !== undefined) $set.time = body.time;
if (body.memory !== undefined) $set.memory = body.memory;
if (body.progress !== undefined) $set.progress = body.progress;
rdoc = await record.update(body.domainId, body.rid, $set, $push);
bus.boardcast('record/change', rdoc, $set, $push);
}
@@ -80,11 +80,11 @@ export async function end(body: JudgeResultBody) {
$push.compilerTexts = body.compilerText;
}
if (body.status) $set.status = body.status;
if (body.score) $set.score = body.score;
if (body.time) $set.time = body.time;
if (body.memory) $set.memory = body.memory;
if (body.score !== undefined) $set.score = body.score;
if (body.time !== undefined) $set.time = body.time;
if (body.memory !== undefined) $set.memory = body.memory;
$set.judgeAt = new Date();
$set.judger = body.judger;
$set.judger = body.judger ?? 1;
rdoc = await record.update(body.domainId, body.rid, $set, $push, $unset);
await _postJudge(rdoc);
bus.boardcast('record/change', rdoc); // trigger a full update
+3 -2
View File
@@ -1,6 +1,7 @@
/* eslint-disable no-await-in-loop */
import cluster from 'cluster';
import { Db, FilterQuery } from 'mongodb';
import { argv } from 'yargs';
import { Logger } from '../logger';
import {
Mdoc, Pdoc, Rdoc, TrainingDoc, User,
@@ -112,7 +113,7 @@ export function emit<K extends keyof EventMap>(name: K, ...args: Parameters<Even
}
export async function serial<K extends keyof EventMap>(name: K, ...args: Parameters<EventMap[K]>): Promise<void> {
logger.debug('serial: %s %o', name, args);
if (argv.showBus) logger.debug('serial: %s %o', name, args);
const hooks = Array.from(_hooks[name] || []);
for (const callback of hooks) {
await callback.apply(this, args);
@@ -120,7 +121,7 @@ export async function serial<K extends keyof EventMap>(name: K, ...args: Paramet
}
export function bail<K extends keyof EventMap>(name: K, ...args: Parameters<EventMap[K]>): ReturnType<EventMap[K]> {
logger.debug('bail: %s %o', name, args);
if (argv.showBus) logger.debug('bail: %s %o', name, args);
const hooks = Array.from(_hooks[name] || []);
for (const callback of hooks) {
const result = callback.apply(this, args);