Skip to content
This repository was archived by the owner on Nov 8, 2020. It is now read-only.

Commit a9e9638

Browse files
committed
test: simple run support
1 parent 9c92201 commit a9e9638

File tree

5 files changed

+86
-5
lines changed

5 files changed

+86
-5
lines changed

judger/hosts/hydro.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ class JudgeTask {
7777
await judger[this.config.type || 'default'].judge(this);
7878
}
7979

80+
async run() {
81+
this.stat.judge = new Date();
82+
await judger.run.judge(this);
83+
}
84+
8085
getNext(that) { // eslint-disable-line class-methods-use-this
8186
that.nextId = 1;
8287
that.nextWaiting = [];

judger/judger/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ module.exports = {
33
submit_snawer: require('./submit_answer'),
44
interactive: require('./interactive'),
55
remotejudge: require('./remotejudge'),
6+
run: require('./run'),
67
};

judger/judger/run.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const {
4+
STATUS_JUDGING, STATUS_COMPILING, STATUS_RUNTIME_ERROR,
5+
STATUS_TIME_LIMIT_EXCEEDED, STATUS_MEMORY_LIMIT_EXCEEDED,
6+
STATUS_ACCEPTED,
7+
} = require('../status');
8+
const { run } = require('../sandbox');
9+
const compile = require('../compile');
10+
const signals = require('../signals');
11+
12+
exports.judge = async (ctx) => {
13+
ctx.stat.judge = new Date();
14+
ctx.next({ status: STATUS_COMPILING });
15+
ctx.execute = await compile(ctx.lang, ctx.code, 'code', {}, ctx.next);
16+
ctx.clean.push(ctx.execute.clean);
17+
ctx.next({ status: STATUS_JUDGING, progress: 0 });
18+
const { copyIn } = ctx.execute;
19+
const stdin = path.resolve(ctx.tmpdir, 'stdin');
20+
const stdout = path.resolve(ctx.tmpdir, 'stdout');
21+
const stderr = path.resolve(ctx.tmpdir, 'stderr');
22+
fs.writeFileSync(stdin, ctx.config.input || '');
23+
const res = await run(
24+
ctx.execute.execute.replace(/\$\{name\}/g, 'code'),
25+
{
26+
stdin,
27+
stdout,
28+
stderr,
29+
copyIn,
30+
time_limit_ms: ctx.config.time,
31+
memory_limit_mb: ctx.config.memory,
32+
},
33+
);
34+
const { code, time_usage_ms, memory_usage_kb } = res;
35+
let { status } = res;
36+
if (!fs.existsSync(stdout)) fs.writeFileSync(stdout, '');
37+
let message = '';
38+
if (status === STATUS_ACCEPTED) {
39+
if (time_usage_ms > ctx.config.time) {
40+
status = STATUS_TIME_LIMIT_EXCEEDED;
41+
} else if (memory_usage_kb > ctx.config.memory * 1024) {
42+
status = STATUS_MEMORY_LIMIT_EXCEEDED;
43+
}
44+
} else if (code) {
45+
status = STATUS_RUNTIME_ERROR;
46+
if (code < 32) message = signals[code];
47+
else message = `您的程序返回了 ${code}.`;
48+
}
49+
ctx.next({
50+
status,
51+
case: {
52+
status,
53+
time_ms: time_usage_ms,
54+
memory_kb: memory_usage_kb,
55+
judge_text: message,
56+
},
57+
});
58+
ctx.stat.done = new Date();
59+
ctx.next({ judge_text: JSON.stringify(ctx.stat) });
60+
ctx.end({
61+
stdout: fs.readFileSync(stdout).toString(),
62+
stderr: fs.readFileSync(stderr).toString(),
63+
time_ms: Math.floor(time_usage_ms * 1000000) / 1000000,
64+
memory_kb: memory_usage_kb,
65+
});
66+
};

module/service.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,28 +129,28 @@ async function postInit() {
129129
this.stat = {};
130130
this.stat.receive = new Date();
131131
this.request = request;
132-
console.log(this.request);
133132
}
134133

135134
async handle() {
136135
try {
137136
this.stat.handle = new Date();
138137
this.event = this.request.event;
139-
this.pid = this.request.pid.toString();
138+
this.pid = (this.request.pid || 'unknown').toString();
140139
this.rid = this.request.rid.toString();
141140
this.domainId = this.request.domainId;
142141
this.lang = this.request.lang;
143142
this.code = this.request.code;
144143
this.data = this.request.data;
144+
this.config = this.request.config;
145145
this.next = getNext(this);
146146
this.end = getEnd(this.domainId, this.rid);
147-
console.log(config.TEMP_DIR, 'tmp', this.rid);
148147
this.tmpdir = path.resolve(config.TEMP_DIR, 'tmp', this.rid);
149148
this.clean = [];
150149
mkdirp(this.tmpdir);
151150
tmpfs.mount(this.tmpdir, '64m');
152151
log.submission(`${this.rid}`, { pid: this.pid });
153152
if (!this.event) await this.submission();
153+
else if (this.event === 'run') await this.run();
154154
else throw new SystemError(`Unsupported type: ${this.type}`);
155155
} catch (e) {
156156
if (e instanceof CompileError) {
@@ -189,10 +189,19 @@ async function postInit() {
189189
this.stat.judge = new Date();
190190
await judger[this.config.type || 'default'].judge(this);
191191
}
192+
193+
async run() {
194+
this.stat.judge = new Date();
195+
await judger.run.judge(this);
196+
}
192197
}
198+
193199
task.consume({ type: 'judge' }, (t) => {
194200
(new JudgeTask(t)).handle().catch((e) => log.error(e));
195201
});
202+
task.consume({ type: 'run' }, (t) => {
203+
(new JudgeTask(t).handle().catch((e) => log.error(e)));
204+
});
196205
}
197206

198207
global.Hydro.service.judger = module.exports = { postInit };

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hydrojudger",
3-
"version": "1.1.1",
3+
"version": "1.2.0",
44
"main": "judger/daemon.js",
55
"author": "masnn",
66
"dependencies": {
@@ -27,7 +27,7 @@
2727
"webpack": "webpack --config webpack.config.js",
2828
"build": "cd module && hydro-build",
2929
"pack": "pkg .",
30-
"lint": "eslint judger build.js service.js --fix"
30+
"lint": "eslint judger module --fix"
3131
},
3232
"pkg": {
3333
"scripts": [

0 commit comments

Comments
 (0)