From 503b69b2e5c3f59b9c3c307a50e711cd8eb8d967 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Thu, 23 Nov 2017 22:52:05 +0800 Subject: [PATCH] feat: dump application router json Store on `run/router.json` --- lib/application.js | 34 +++++++++++++++++-- package.json | 2 +- .../config/config.unittest.js | 5 +++ test/fixtures/apps/demo/app.js | 2 ++ test/fixtures/apps/demo/app/controller/obj.js | 19 +++++++++++ .../fixtures/apps/demo/app/controller/obj2.js | 19 +++++++++++ test/fixtures/apps/demo/app/router.js | 8 +++++ test/lib/core/httpclient.test.js | 6 ++++ test/lib/egg.test.js | 17 ++++++++++ 9 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/apps/base-context-class/config/config.unittest.js create mode 100644 test/fixtures/apps/demo/app/controller/obj.js create mode 100644 test/fixtures/apps/demo/app/controller/obj2.js diff --git a/lib/application.js b/lib/application.js index f33b3142e9..05e0402e2b 100644 --- a/lib/application.js +++ b/lib/application.js @@ -1,13 +1,14 @@ 'use strict'; const path = require('path'); +const fs = require('fs'); const graceful = require('graceful'); const http = require('http'); -const EggApplication = require('./egg'); -const AppWorkerLoader = require('./loader').AppWorkerLoader; const cluster = require('cluster-client'); const { assign } = require('utility'); const eggUtils = require('egg-core').utils; +const EggApplication = require('./egg'); +const AppWorkerLoader = require('./loader').AppWorkerLoader; const KEYS = Symbol('Application#keys'); const HELPER = Symbol('Application#Helper'); @@ -116,6 +117,35 @@ class Application extends EggApplication { return context; } + /** + * save routers to `run/router.json` + * @private + */ + dumpConfig() { + super.dumpConfig(); + + // dump routers to router.json + const rundir = this.config.rundir; + const FULLPATH = this.loader.FileLoader.FULLPATH; + try { + const dumpRouterFile = path.join(rundir, 'router.json'); + const routers = []; + for (const layer of this.router.stack) { + routers.push({ + name: layer.name, + methods: layer.methods, + paramNames: layer.paramNames, + path: layer.path, + regexp: layer.regexp.toString(), + stack: layer.stack.map(stack => stack[FULLPATH] || stack._name || stack.name || 'anonymous'), + }); + } + fs.writeFileSync(dumpRouterFile, JSON.stringify(routers, null, 2)); + } catch (err) { + this.coreLogger.warn(`dumpConfig router.json error: ${err.message}`); + } + } + /** * Create an anonymous context, the context isn't request level, so the request is mocked. * then you can use context level API like `ctx.service` diff --git a/package.json b/package.json index 6b0c1c135c..5422f40eab 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "delegates": "^1.0.0", "egg-cluster": "^1.12.5", "egg-cookies": "^2.2.1", - "egg-core": "^4.1.0", + "egg-core": "^4.2.0", "egg-development": "^2.0.0", "egg-i18n": "^2.0.0", "egg-jsonp": "^2.0.0", diff --git a/test/fixtures/apps/base-context-class/config/config.unittest.js b/test/fixtures/apps/base-context-class/config/config.unittest.js new file mode 100644 index 0000000000..d108222fe3 --- /dev/null +++ b/test/fixtures/apps/base-context-class/config/config.unittest.js @@ -0,0 +1,5 @@ +'use strict'; + +exports.logger = { + consoleLevel: 'NONE', +}; diff --git a/test/fixtures/apps/demo/app.js b/test/fixtures/apps/demo/app.js index fd4ac86a91..d0eece8635 100644 --- a/test/fixtures/apps/demo/app.js +++ b/test/fixtures/apps/demo/app.js @@ -3,5 +3,7 @@ module.exports = app => { app.ready(() => { app.config.tips = 'hello egg started'; + // dynamic router + app.all('/all', app.controller.home); }); }; diff --git a/test/fixtures/apps/demo/app/controller/obj.js b/test/fixtures/apps/demo/app/controller/obj.js new file mode 100644 index 0000000000..260b80c6e6 --- /dev/null +++ b/test/fixtures/apps/demo/app/controller/obj.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = app => { + return { + * bar() { + this.ctx.body = 'this is obj bar!'; + }, + + * error() { + aaa; + }, + + subObj: { + * hello() { + this.ctx.body = 'this is subObj hello!'; + }, + }, + }; +}; diff --git a/test/fixtures/apps/demo/app/controller/obj2.js b/test/fixtures/apps/demo/app/controller/obj2.js new file mode 100644 index 0000000000..9817c45eee --- /dev/null +++ b/test/fixtures/apps/demo/app/controller/obj2.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = { + * bar() { + this.ctx.body = 'this is obj bar!'; + }, + + subObj: { + * hello() { + this.ctx.body = 'this is subObj hello!'; + }, + + subSubObj: { + * hello() { + this.ctx.body = 'this is subSubObj hello!'; + }, + }, + }, +}; diff --git a/test/fixtures/apps/demo/app/router.js b/test/fixtures/apps/demo/app/router.js index 8becb4d53c..80a81c057e 100644 --- a/test/fixtures/apps/demo/app/router.js +++ b/test/fixtures/apps/demo/app/router.js @@ -12,4 +12,12 @@ module.exports = app => { app.get('/ip', app.controller.ip); app.get('/class-controller', 'foo.bar'); + + app.get('/obj-controller', 'obj.bar'); + app.get('/obj-error', 'obj.error'); + app.get('/subobj-controller', 'obj.subObj.hello'); + + app.get('/obj2-controller', app.controller.obj2.bar); + app.get('/subobj2-controller', app.controller.obj2.subObj.hello); + app.get('/subSubObj-hello', app.controller.obj2.subObj.subSubObj.hello); }; diff --git a/test/lib/core/httpclient.test.js b/test/lib/core/httpclient.test.js index ae93a56df2..7ba09f0921 100644 --- a/test/lib/core/httpclient.test.js +++ b/test/lib/core/httpclient.test.js @@ -327,17 +327,20 @@ describe('test/lib/core/httpclient.test.js', () => { let res = await httpclient.request(url, { method: 'GET', + timeout: 20000, }); assert(res.status === 200); res = await httpclient.request('https://github.com', { method: 'GET', + timeout: 20000, }); assert(res.status === 200); res = await httpclient.request('https://www.npmjs.com', { method: 'GET', + timeout: 20000, }); assert(res.status === 200); @@ -360,16 +363,19 @@ describe('test/lib/core/httpclient.test.js', () => { res = await httpclient.request(url, { method: 'GET', + timeout: 20000, }); assert(res.status === 200); res = await httpclient.request('https://github.com', { method: 'GET', + timeout: 20000, }); assert(res.status === 200); res = await httpclient.request('https://www.npmjs.com', { method: 'GET', + timeout: 20000, }); assert(res.status === 200); diff --git a/test/lib/egg.test.js b/test/lib/egg.test.js index 889065c8f9..1a2d78ecf5 100644 --- a/test/lib/egg.test.js +++ b/test/lib/egg.test.js @@ -28,9 +28,26 @@ describe('test/lib/egg.test.js', () => { assert(json.config.tips === 'hello egg'); json = require(path.join(baseDir, 'run/application_config.json')); assert(/\d+\.\d+\.\d+/.test(json.plugins.onerror.version)); + // should dump dynamic config assert(json.config.tips === 'hello egg started'); }); + it('should dump router json', () => { + const routers = require(path.join(baseDir, 'run/router.json')); + // 13 static routers on app/router.js and 1 dynamic router on app.js + assert(routers.length === 14); + for (const router of routers) { + assert.deepEqual(Object.keys(router), [ + 'name', + 'methods', + 'paramNames', + 'path', + 'regexp', + 'stack', + ]); + } + }); + it('should dump config meta', () => { let json = require(path.join(baseDir, 'run/agent_config_meta.json')); assert(json.name === path.join(__dirname, '../../config/config.default.js'));