test: judger intergration

This commit is contained in:
masnn committed 2020-05-12 12:20:21 +08:00
1 parent 1cdca971ea
commit 90b06d6aa7
5 files changed
+110 -55

No files matched your search

+38 -10
View File
@@ -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
View File
@@ -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 = {
+61 -40
View File
@@ -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'];
maxAge: 365 * 24 * 60 * 60, app.use(cache(path.join(process.cwd(), '.uibuild'), {
})); maxAge: 365 * 24 * 60 * 60,
app.use(Body({
multipart: true,
formidable: {
maxFileSize: 256 * 1024 * 1024,
},
}));
router.get('/', async (ctx) => {
ctx.body = await render('setup.html');
ctx.response.type = 'text/html';
});
router.post('/', async (ctx) => {
const {
host, port, name, username, password,
} = ctx.request.body;
fs.writeFileSync(path.resolve(process.cwd(), 'config.json'), JSON.stringify({
host, port, name, username, password,
})); }));
ctx.body = await render('setup_done.html'); app.use(Body({ formidable: { maxFileSize: 256 * 1024 * 1024 } }));
ctx.response.type = 'text/html'; router.get('/', async (ctx) => {
}); ctx.body = await render('setup.html');
ctx.response.type = 'text/html';
});
const p = new Promise((resolve) => {
router.post('/', async (ctx) => {
const {
host, port, name, username, password,
} = 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({
host, port, name, username, password,
}));
ctx.redirect('/');
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');
+4
View File
@@ -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));
}; };
+7 -4
View File
@@ -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);