Skip to content

Instantly share code, notes, and snippets.

@xiongjia
Last active September 14, 2017 07:42
Show Gist options
  • Save xiongjia/428402521312456ceccf to your computer and use it in GitHub Desktop.
Save xiongjia/428402521312456ceccf to your computer and use it in GitHub Desktop.
Mock Server #devtools

Mock Server

Installation

  1. Clone this gist to a local folder
  2. Run npm install in the local folder

Usage

  • Launch the server:
    node index.js
  • Launch the server with cluster feature: node index.js --cluster --workers 5
    ("--workers 5" is the working processes number.)

Test URLs

  • "/get-data" - Server send the data back with customer's requirement. For instance:
    • http://localhost:2333/get-data?len=2048&delay=500
      Server sends 2048 bytes data back after 500 (ms).
    • http://localhost:2333/get-data
      Server sends 1024 bytes data back and no delay.
  • "basic-auth" - The base HTTP authorization test. (The test user name is "mock" & password is "mock" as well.)
    For instance: http://localhost:2333/basic-auth
node_modules
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": "vars",
"boss": true,
"eqnull": true,
"node": true,
"trailing": true,
"strict": true,
"indent": 2,
"predef": [ "describe", "it", "xit", "before", "after", "beforeEach", "afterEach" ]
}
'use strict';
var logger = require('winston'),
http = require('http'),
cluster = require('cluster'),
util = require('util'),
os = require('os'),
connect = require('connect'),
_ = require('underscore'),
dbg = require('debug')('mockSrv'),
exitCode = { ok: 0, fatal: -1, servStartupErr: -5, usage: 10 },
optimist = require('optimist')
.alias('h', 'help')
.describe('logLevel', 'Controls the verbosity of the ErrorLog')
.describe('workers', 'The number of worker processes')
.describe('cluster', 'Enable cluster')
.describe('port', 'Set the server port number');
function startupServ(options) {
var srv, started, app, mockRepBuf, mockRepBufLen;
/* create http server */
mockRepBuf = '01234567890123456789012345678901234567890123456789';
_.times(10, function () { mockRepBuf += mockRepBuf; });
mockRepBufLen = mockRepBuf.length;
logger.debug('Mock repBuf is created. (len=%d)', mockRepBufLen);
started = false;
app = connect();
if (options.reqLogger) {
/* enable request logger */
app.use(connect.logger('dev'));
}
app.use(connect.query())
.use('/basic-auth', connect.basicAuth(function(user, pass){
dbg('basic-auth request (user=%s; pass=%s; pid=%d)',
user, pass, process.pid);
return user === 'mock' && pass === 'mock';
}))
.use('/basic-auth', function (req, res) {
dbg('basic-auth passed');
res.writeHead(200, { 'Content-Type': 'text/plain', 'Server': 'mserv' });
res.end('Authorized');
})
.use('/get-data', function(req, res) {
var repLen, repDelay;
/* check parameters */
repLen = req.query.len || 1024;
repLen = Math.max(repLen, 1);
repDelay = req.query.delay || 0;
dbg('get-data request (len=%d, delay=%d)', repLen, repDelay);
/* send data to client */
function sndData() {
var sndLen;
res.writeHead(200, { 'Content-Type': 'text/plain', 'Server': 'mserv' });
for (sndLen = 0; sndLen < repLen;) {
if ((mockRepBufLen + sndLen) > repLen) {
/* the last piece */
res.write(mockRepBuf.substr(0, repLen - sndLen));
sndLen = repLen;
}
else {
res.write(mockRepBuf);
sndLen += mockRepBufLen;
}
}
res.end();
}
if (repDelay <= 0) {
sndData();
}
else {
setTimeout(sndData, repDelay);
}
})
.use(function(req, res) {
dbg('http req, pid %d', process.pid);
res.writeHead(200, { 'Content-Type': 'text/plain', 'Server': 'mserv' });
res.end(util.format('HTTP(s) Mock Server. PID=%d\n', process.pid));
});
srv = http.createServer(app);
srv.on('error', function (err) {
logger.error('Server error: %s', err.toString());
if (!started) {
logger.error('Server startup failed.');
process.exit(exitCode.servStartupErr);
}
}).on('close', function () {
logger.debug('Server closed. (pid=%d)', process.pid);
});
srv.listen(options.port, function () {
started = true;
logger.info('Server started. (Port=%d)', options.port);
});
}
(function (argv) {
var workers, srvOpts;
if (argv.help) {
optimist.showHelp();
process.exit(exitCode.usage);
}
/* startup logger */
logger.cli();
logger['default'].transports.console.level = argv.logLevel || 'debug';
logger['default'].transports.console.timestamp = true;
if (argv.cluster && cluster.isMaster) {
logger.debug('Master process is creating the workers.');
workers = argv.workers || os.cpus().length;
_.times(Math.max(workers, 1), function () {
var wrk = cluster.fork();
logger.debug('The worker(%d) has been created.', wrk.id);
});
cluster.on('exit', function (worker, code, signal) {
logger.info('The worker(%d) exited. (pid=%d, code=%d, signal=%d)',
worker.id, worker.process.pid, code, signal);
});
}
else {
/* create the server */
srvOpts = {
port: argv.port || 2333,
reqLogger: argv.reqLogger
};
logger.debug('Worker process(%d) is creating the server: %j',
process.pid, srvOpts, {});
startupServ(srvOpts);
}
})(optimist.argv);
{
"name": "mserv",
"version": "0.0.1",
"description": "Mock Server",
"main": "index.js",
"scripts": {
"test": "node index.js"
},
"author": "",
"license": "BSD-2-Clause",
"dependencies": {
"optimist": "~0.6.1",
"winston": "~0.7.3",
"underscore": "~1.6.0",
"connect": "~2.15.0",
"debug": "~0.8.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment