mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 09:46:28 +08:00
test: judger intergration
This commit is contained in:
1 parent
1cdca971ea
commit
90b06d6aa7
5 files changed
+97
-42
No files matched your search
+38
-10
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable import/no-dynamic-require */
|
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
/* eslint-disable no-eval */
|
/* eslint-disable no-eval */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -21,20 +20,35 @@ function ensureDir(dir) {
|
|||||||
|
|
||||||
const active = [];
|
const active = [];
|
||||||
try {
|
try {
|
||||||
|
// Let webpack pack builtin module together.
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
const f = require('../.build/builtin.json');
|
const f = require('../.build/builtin.json');
|
||||||
const m = { ...yaml.safeLoad(zlib.gunzipSync(f.data)), id: 'builtin' };
|
const m = { ...yaml.safeLoad(zlib.gunzipSync(f.data)), id: 'builtin' };
|
||||||
active.push(m);
|
active.push(m);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
/* Ignore */
|
// Builtin module is in the module directory
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleRoots = [
|
||||||
|
root('.build/module'),
|
||||||
|
root('module'),
|
||||||
|
root(path.resolve(os.homedir(), '.hydro', 'module')),
|
||||||
|
root('.'),
|
||||||
|
];
|
||||||
|
let moduleRoot;
|
||||||
|
for (const i of moduleRoots) {
|
||||||
|
if (fs.existsSync(i) && fs.statSync(i).isDirectory()) {
|
||||||
|
moduleRoot = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function preload() {
|
async function preload() {
|
||||||
const files = fs.readdirSync(root('.build/module'));
|
const files = fs.readdirSync(moduleRoot);
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
if (file.endsWith('.hydro')) {
|
if (file.endsWith('.hydro')) {
|
||||||
try {
|
try {
|
||||||
const f = fs.readFileSync(root(`.build/module/${file}`));
|
const f = fs.readFileSync(root(`${moduleRoot}/${file}`));
|
||||||
const m = { ...yaml.safeLoad(zlib.gunzipSync(f)), id: file.split('.')[0] };
|
const m = { ...yaml.safeLoad(zlib.gunzipSync(f)), id: file.split('.')[0] };
|
||||||
active.push(m);
|
active.push(m);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -61,6 +75,8 @@ async function preload() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Module Load Fail: ${i.id}`);
|
console.error(`Module Load Fail: ${i.id}`);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -69,7 +85,7 @@ async function preload() {
|
|||||||
|
|
||||||
async function handler() {
|
async function handler() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.handler) {
|
if (i.handler && !i.fail) {
|
||||||
try {
|
try {
|
||||||
console.time(`Handler init: ${i.id}`);
|
console.time(`Handler init: ${i.id}`);
|
||||||
const exports = {};
|
const exports = {};
|
||||||
@@ -78,6 +94,8 @@ async function handler() {
|
|||||||
eval(i.handler);
|
eval(i.handler);
|
||||||
console.timeEnd(`Handler init: ${i.id}`);
|
console.timeEnd(`Handler init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Handler Load Fail: ${i.id}`);
|
console.error(`Handler Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,11 +104,13 @@ async function handler() {
|
|||||||
|
|
||||||
async function locale() {
|
async function locale() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.locale) {
|
if (i.locale && !i.fail) {
|
||||||
try {
|
try {
|
||||||
global.Hydro.lib.i18n(i.locale);
|
global.Hydro.lib.i18n(i.locale);
|
||||||
console.log(`Locale init: ${i.id}`);
|
console.log(`Locale init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Locale Load Fail: ${i.id}`);
|
console.error(`Locale Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,11 +119,13 @@ async function locale() {
|
|||||||
|
|
||||||
async function template() {
|
async function template() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.template) {
|
if (i.template && !i.fail) {
|
||||||
try {
|
try {
|
||||||
Object.assign(global.Hydro.template, i.template);
|
Object.assign(global.Hydro.template, i.template);
|
||||||
console.log(`Template init: ${i.id}`);
|
console.log(`Template init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Template Load Fail: ${i.id}`);
|
console.error(`Template Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +134,7 @@ async function template() {
|
|||||||
|
|
||||||
async function model() {
|
async function model() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.model) {
|
if (i.model && !i.fail) {
|
||||||
try {
|
try {
|
||||||
console.time(`Model init: ${i.id}`);
|
console.time(`Model init: ${i.id}`);
|
||||||
const exports = {};
|
const exports = {};
|
||||||
@@ -121,6 +143,8 @@ async function model() {
|
|||||||
if ((module.exports || {}).index) await module.exports.index();
|
if ((module.exports || {}).index) await module.exports.index();
|
||||||
console.timeEnd(`Model init: ${i.id}`);
|
console.timeEnd(`Model init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Model Load Fail: ${i.id}`);
|
console.error(`Model Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +153,7 @@ async function model() {
|
|||||||
|
|
||||||
async function lib() {
|
async function lib() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.lib) {
|
if (i.lib && !i.fail) {
|
||||||
try {
|
try {
|
||||||
console.time(`Lib init: ${i.id}`);
|
console.time(`Lib init: ${i.id}`);
|
||||||
const exports = {};
|
const exports = {};
|
||||||
@@ -138,6 +162,8 @@ async function lib() {
|
|||||||
eval(i.lib);
|
eval(i.lib);
|
||||||
console.timeEnd(`Lib init: ${i.id}`);
|
console.timeEnd(`Lib init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Lib Load Fail: ${i.id}`);
|
console.error(`Lib Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +172,7 @@ async function lib() {
|
|||||||
|
|
||||||
async function service() {
|
async function service() {
|
||||||
for (const i of active) {
|
for (const i of active) {
|
||||||
if (i.service) {
|
if (i.service && !i.fail) {
|
||||||
try {
|
try {
|
||||||
console.time(`Service init: ${i.id}`);
|
console.time(`Service init: ${i.id}`);
|
||||||
const exports = {}; // eslint-disable-line no-unused-vars
|
const exports = {}; // eslint-disable-line no-unused-vars
|
||||||
@@ -155,6 +181,8 @@ async function service() {
|
|||||||
if ((module.exports || {}).init) await module.exports.init();
|
if ((module.exports || {}).init) await module.exports.init();
|
||||||
console.timeEnd(`Service init: ${i.id}`);
|
console.timeEnd(`Service init: ${i.id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
i.fail = true;
|
||||||
|
fail.push(i.id);
|
||||||
console.error(`Service Load Fail: ${i.id}`);
|
console.error(`Service Load Fail: ${i.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const yaml = require('js-yaml');
|
|
||||||
const { defaultsDeep } = require('lodash');
|
const { defaultsDeep } = require('lodash');
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
|
|||||||
+48
-27
@@ -1,21 +1,23 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const http = require('http');
|
||||||
const Koa = require('koa');
|
const Koa = require('koa');
|
||||||
const morgan = require('koa-morgan');
|
const morgan = require('koa-morgan');
|
||||||
const Body = require('koa-body');
|
const Body = require('koa-body');
|
||||||
const Router = require('koa-router');
|
const Router = require('koa-router');
|
||||||
const cache = require('koa-static-cache');
|
const cache = require('koa-static-cache');
|
||||||
const http = require('http');
|
|
||||||
const nunjucks = require('nunjucks');
|
const nunjucks = require('nunjucks');
|
||||||
|
const mongodb = require('mongodb');
|
||||||
|
|
||||||
function Loader() { }
|
class Loader {
|
||||||
Loader.prototype.getSource = function getSource(name) {
|
getSource(name) { // eslint-disable-line class-methods-use-this
|
||||||
if (!global.Hydro.template[name]) throw new Error(`Cannot get template ${name}`);
|
if (!global.Hydro.template[name]) throw new Error(`Cannot get template ${name}`);
|
||||||
return {
|
return {
|
||||||
src: global.Hydro.template[name],
|
src: global.Hydro.template[name],
|
||||||
path: name,
|
path: name,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Nunjucks extends nunjucks.Environment {
|
class Nunjucks extends nunjucks.Environment {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -38,36 +40,55 @@ function render(name) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const app = new Koa();
|
async function setup() {
|
||||||
const server = http.createServer(app.callback());
|
const app = new Koa();
|
||||||
const router = new Router();
|
const server = http.createServer(app.callback());
|
||||||
app.keys = ['Hydro'];
|
const router = new Router();
|
||||||
app.use(cache(path.join(process.cwd(), '.uibuild'), {
|
app.keys = ['Hydro'];
|
||||||
|
app.use(cache(path.join(process.cwd(), '.uibuild'), {
|
||||||
maxAge: 365 * 24 * 60 * 60,
|
maxAge: 365 * 24 * 60 * 60,
|
||||||
}));
|
}));
|
||||||
app.use(Body({
|
app.use(Body({ formidable: { maxFileSize: 256 * 1024 * 1024 } }));
|
||||||
multipart: true,
|
router.get('/', async (ctx) => {
|
||||||
formidable: {
|
|
||||||
maxFileSize: 256 * 1024 * 1024,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
router.get('/', async (ctx) => {
|
|
||||||
ctx.body = await render('setup.html');
|
ctx.body = await render('setup.html');
|
||||||
ctx.response.type = 'text/html';
|
ctx.response.type = 'text/html';
|
||||||
});
|
});
|
||||||
router.post('/', async (ctx) => {
|
const p = new Promise((resolve) => {
|
||||||
|
router.post('/', async (ctx) => {
|
||||||
const {
|
const {
|
||||||
host, port, name, username, password,
|
host, port, name, username, password,
|
||||||
} = ctx.request.body;
|
} = ctx.request.body;
|
||||||
|
let mongourl = 'mongodb://';
|
||||||
|
if (username) mongourl += `${username}:${password}@`;
|
||||||
|
mongourl += `${host}:${port}/${name}`;
|
||||||
|
try {
|
||||||
|
const Database = await mongodb.MongoClient.connect(mongourl, {
|
||||||
|
useNewUrlParser: true, useUnifiedTopology: true,
|
||||||
|
});
|
||||||
|
const db = Database.db(name);
|
||||||
|
// Check Write Access
|
||||||
|
await db.collection('test').insertOne({ test: 'test' });
|
||||||
fs.writeFileSync(path.resolve(process.cwd(), 'config.json'), JSON.stringify({
|
fs.writeFileSync(path.resolve(process.cwd(), 'config.json'), JSON.stringify({
|
||||||
host, port, name, username, password,
|
host, port, name, username, password,
|
||||||
}));
|
}));
|
||||||
ctx.body = await render('setup_done.html');
|
ctx.redirect('/');
|
||||||
ctx.response.type = 'text/html';
|
resolve();
|
||||||
});
|
} catch (e) {
|
||||||
|
ctx.body = `Error connecting to database: ${e.message}\n${e.stack}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
|
||||||
|
app.use(router.routes()).use(router.allowedMethods());
|
||||||
|
server.listen(8888);
|
||||||
|
console.log('Server listening at: 8888');
|
||||||
|
await p;
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
server.close((err) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
|
module.exports = { setup };
|
||||||
app.use(router.routes()).use(router.allowedMethods());
|
|
||||||
server.listen(8888);
|
|
||||||
console.log('Server listening at: 8888');
|
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const child = require('child_process');
|
const child = require('child_process');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
|
||||||
exports.prebuild = async function prebuild() {
|
exports.prebuild = async function prebuild() {
|
||||||
if (!fs.existsSync(path.resolve(__dirname, 'HydroJudger'))) {
|
if (!fs.existsSync(path.resolve(__dirname, 'HydroJudger'))) {
|
||||||
const res = child.spawnSync('git clone https://github.com/hydro-dev/HydroJudger.git');
|
const res = child.spawnSync('git clone https://github.com/hydro-dev/HydroJudger.git');
|
||||||
if (res.error) throw res.error;
|
if (res.error) throw res.error;
|
||||||
}
|
}
|
||||||
|
let lang = fs.readFileSync(path.resolve(__dirname, 'langs.yaml')).toString();
|
||||||
|
lang = yaml.safeLoad(lang);
|
||||||
|
fs.writeFileSync(path.resolve(__dirname, '__lang.json'), JSON.stringify(lang));
|
||||||
};
|
};
|
||||||
@@ -3,9 +3,11 @@ const path = require('path');
|
|||||||
const child = require('child_process');
|
const child = require('child_process');
|
||||||
|
|
||||||
async function postInit() {
|
async function postInit() {
|
||||||
|
const config = require('./HydroJudger/judger/config');
|
||||||
|
// eslint-disable-next-line import/no-unresolved
|
||||||
|
config.LANGS = require('./__langs.json');
|
||||||
const { mkdirp, rmdir, compilerText } = require('./HydroJudger/judger/utils');
|
const { mkdirp, rmdir, compilerText } = require('./HydroJudger/judger/utils');
|
||||||
const log = require('./HydroJudger/judger/log');
|
const log = require('./HydroJudger/judger/log');
|
||||||
const { CACHE_DIR, TEMP_DIR } = require('./HydroJudger/judger/config');
|
|
||||||
const tmpfs = require('./HydroJudger/judger/tmpfs');
|
const tmpfs = require('./HydroJudger/judger/tmpfs');
|
||||||
const { FormatError, CompileError, SystemError } = require('./HydroJudger/judger/error');
|
const { FormatError, CompileError, SystemError } = require('./HydroJudger/judger/error');
|
||||||
const { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } = require('./HydroJudger/judger/status');
|
const { STATUS_COMPILE_ERROR, STATUS_SYSTEM_ERROR } = require('./HydroJudger/judger/status');
|
||||||
@@ -17,7 +19,7 @@ async function postInit() {
|
|||||||
const { judge } = global.Hydro.handler;
|
const { judge } = global.Hydro.handler;
|
||||||
|
|
||||||
async function problemData(pid, savePath) {
|
async function problemData(pid, savePath) {
|
||||||
const tmpFilePath = path.resolve(CACHE_DIR, `download_${pid}`);
|
const tmpFilePath = path.resolve(config.CACHE_DIR, `download_${pid}`);
|
||||||
const res = await problem.getData(pid);
|
const res = await problem.getData(pid);
|
||||||
const w = await fs.createWriteStream(tmpFilePath);
|
const w = await fs.createWriteStream(tmpFilePath);
|
||||||
res.data.pipe(w);
|
res.data.pipe(w);
|
||||||
@@ -38,7 +40,7 @@ async function postInit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function cacheOpen(pid, version) {
|
async function cacheOpen(pid, version) {
|
||||||
const filePath = path.join(CACHE_DIR, pid);
|
const filePath = path.join(config.CACHE_DIR, pid);
|
||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
let ver;
|
let ver;
|
||||||
try {
|
try {
|
||||||
@@ -112,7 +114,7 @@ async function postInit() {
|
|||||||
this.data = this.request.data;
|
this.data = this.request.data;
|
||||||
this.next = getNext(this);
|
this.next = getNext(this);
|
||||||
this.end = getEnd(this.rid);
|
this.end = getEnd(this.rid);
|
||||||
this.tmpdir = path.resolve(TEMP_DIR, 'tmp', this.rid);
|
this.tmpdir = path.resolve(config.TEMP_DIR, 'tmp', this.rid);
|
||||||
this.clean = [];
|
this.clean = [];
|
||||||
mkdirp(this.tmpdir);
|
mkdirp(this.tmpdir);
|
||||||
tmpfs.mount(this.tmpdir, '64m');
|
tmpfs.mount(this.tmpdir, '64m');
|
||||||
@@ -138,6 +140,7 @@ async function postInit() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
for (const clean of this.clean) await clean().catch();
|
for (const clean of this.clean) await clean().catch();
|
||||||
tmpfs.umount(this.tmpdir);
|
tmpfs.umount(this.tmpdir);
|
||||||
await rmdir(this.tmpdir);
|
await rmdir(this.tmpdir);
|
||||||
|
|||||||
Reference in new issue
Block a user