Finally solved unit test anomaly...

This commit is contained in:
Dominic Bosch 2014-02-20 10:17:06 +01:00
parent e31da1e5a0
commit 108432762e
9 changed files with 168 additions and 126 deletions

View file

@ -79,20 +79,26 @@ initRouting = ( port ) =>
app.post '/logout', requestHandler.handleLogout
# - **`POST` to _"/user"_:** User requests are possible for all users with an account
app.post '/usercommand', requestHandler.handleUserCommand
try
server = app.listen parseInt( port ) || 8125 # inbound event channel
server = app.listen parseInt( port ) || 8111 # inbound event channel
server.on 'listening', () =>
addr = server.address()
if addr.port isnt port
@shutDownSystem()
server.on 'error', ( err ) =>
###
Error handling of the express port listener requires special attention,
thus we have to catch the error, which is issued if the port is already in use.
###
server.on 'listening', () =>
addr = server.address()
if addr.port is not port
@shutDownSystem()
server.on 'error', ( err ) =>
if err.errno is 'EADDRINUSE'
switch err.errno
when 'EADDRINUSE'
@log.error err, 'HL | http-port already in use, shutting down!'
@shutDownSystem()
when 'EACCES'
@log.error err, 'HL | http-port not accessible, shutting down!'
else
@log.error err, 'HL | Error in server, shutting down!'
@shutDownSystem()
###
@ -106,15 +112,16 @@ exports.addShutdownHandler = ( fShutDown ) =>
requestHandler.addShutdownHandler fShutDown
# There's no way to gracefully stop express from running, thus the main
# module needs to call process.exit() at the very end of its existance... thanks
# ###
# Shuts down the http listener.
# There's no way to gracefully stop express from running, thus we
# call process.exit() at the very end of our existance.
# ... but process.exit cancels the unit tests ...
# thus we do it in the main module and use a cli flag for the unit tests
# @public shutDown()
# ###
# exports.shutDown = () =>
# @log?.warn 'HL | Shutting down HTTP listener'
# # Yeah I know the discussion... let's assume the system runs forever
# console.log 'exiting...'
# process.exit()

View file

@ -26,12 +26,9 @@ Returns a bunyan logger according to the given arguments.
###
exports.getLogger = ( args ) =>
emptylog =
{
info: () ->
warn: () ->
error: () ->
getLog: () ->
}
info: () ->
warn: () ->
error: () ->
# `args` holds the configuration settings for the logging, see either CLI arguments
# in [webapi-eca](webapi-eca.html) or the configuration parameters in [config](config.html).
args = args ? {}

View file

@ -80,6 +80,12 @@ opt =
'n':
alias : 'nolog',
describe: 'Set this if no output shall be generated'
# `-n`, `--nolog`: Set this if no output shall be generated
'u':
alias : 'unit-test-flag',
describe: """Set this if you are running the unit tests. This will cause the
system to not call process.exit() at the end of the shutDown routine
in order to get rid of the express server that would keep running"""
# now fetch the CLI arguments and exit if the help has been called.
argv = optimist.usage( usage ).options( opt ).argv
@ -99,6 +105,7 @@ init = =>
console.error 'FAIL: Config file not ready! Shutting down...'
process.exit()
@isUnitTest = argv.u || false
logconf = conf.getLogConf()
if argv.m
logconf[ 'mode' ] = argv.m
@ -161,10 +168,11 @@ Shuts down the server.
@private shutDown()
###
shutDown = =>
shutDown = () =>
@log.warn 'RS | Received shut down command!'
engine?.shutDown()
# We need to force stop express (in http-listener module)
# We need to call process.exit() since the express server in the http-listener
# can't be stopped gracefully. Why would you stop this system anyways!??
process.exit()
###

View file

@ -64,27 +64,32 @@ HTTP Listener
app.post('/login', requestHandler.handleLogin);
app.post('/logout', requestHandler.handleLogout);
app.post('/usercommand', requestHandler.handleUserCommand);
try {
server = app.listen(parseInt(port) || 8125);
server = app.listen(parseInt(port) || 8111);
server.on('listening', function() {
var addr;
addr = server.address();
if (addr.port !== port) {
return _this.shutDownSystem();
}
});
return server.on('error', function(err) {
/*
Error handling of the express port listener requires special attention,
thus we have to catch the error, which is issued if the port is already in use.
*/
server.on('listening', function() {
var addr;
addr = server.address();
if (addr.port === !port) {
return _this.shutDownSystem();
}
});
return server.on('error', function(err) {
if (err.errno === 'EADDRINUSE') {
switch (err.errno) {
case 'EADDRINUSE':
_this.log.error(err, 'HL | http-port already in use, shutting down!');
return _this.shutDownSystem();
}
});
} catch (_error) {}
break;
case 'EACCES':
_this.log.error(err, 'HL | http-port not accessible, shutting down!');
break;
default:
_this.log.error(err, 'HL | Error in server, shutting down!');
}
return _this.shutDownSystem();
});
};
/*

View file

@ -22,8 +22,7 @@
emptylog = {
info: function() {},
warn: function() {},
error: function() {},
getLog: function() {}
error: function() {}
};
args = args != null ? args : {};
if (args.nolog) {

View file

@ -79,6 +79,10 @@ WebAPI-ECA Engine
'n': {
alias: 'nolog',
describe: 'Set this if no output shall be generated'
},
'u': {
alias: 'unit-test-flag',
describe: "Set this if you are running the unit tests. This will cause the\nsystem to not call process.exit() at the end of the shutDown routine\nin order to get rid of the express server that would keep running"
}
};
@ -103,6 +107,7 @@ WebAPI-ECA Engine
console.error('FAIL: Config file not ready! Shutting down...');
process.exit();
}
_this.isUnitTest = argv.u || false;
logconf = conf.getLogConf();
if (argv.m) {
logconf['mode'] = argv.m;

View file

@ -1,79 +1,87 @@
path = require 'path'
needle = require 'needle'
logger = require path.join '..', 'js-coffee', 'logging'
log = logger.getLogger
nolog: true
#
# WARNING
#
# We would need to create a helper/wrapper module to test the http-listener.
# This is because the creation of an express server leaves us with an ever running
# server that can't be stopped because of its asynchronity. We need to call
# process.exit() at the very and of an existance of such an instance.
# But calling this will also cause the unit test to stop.
# Thus we could only test this module by creating a helper/wrapper module and
# forking a child process for it, which we then could kill.
#
# All functionality can anyways be tested within its parent (webapi-eca), thus
# we won't make the effort with the helper/wrapper module for now.
#
exports.testShutDown = ( test ) =>
exports.testsGoInWebAPI_ECA_Module = ( test ) ->
test.expect 1
http = require path.join '..', 'js-coffee', 'http-listener'
http.addShutdownHandler () ->
console.log 'shutdown handler called!'
http.shutDown()
test.done()
process.exit()
args = {
logger: log
}
args[ 'http-port' ] = 8080
http args
test.ok true, 'yay'
fWait = () ->
needle.get 'localhost:8080/forge_modules', (err, resp, body) ->
console.log 'http'
# console.log http
# console.log test
# console.log err
# console.log resp
# console.log body
test.done()
if err
console.log 'got an error on request'
console.log err
else
console.log 'no err'
if resp and resp.statusCode is 200
console.log 'yay got valid answer'
else console.log 'got an'
try
console.log 'trying to shutdown'
console.log http
http.shutDown()
catch e
console.log e
setTimeout fWait, 1000
exports.testWrongPort = ( test ) =>
test.expect 1
test.ok true, 'yay'
test.ok true, 'All tests for this should be implemented in the webapi-eca module'
test.done()
# http = require path.join '..', 'js-coffee', 'http-listener'
# http.addShutDownHandler () ->
# test.done()
# engine = cp.fork pth, [ '-n' ] # [ '-i' , 'warn' ]
# engine.on 'exit', ( code, signal ) ->
# test.ok true, 'Engine stopped'
# isRunning = false
# test.done()
# fWaitForStartup = () ->
# engine.send 'die'
# setTimeout fWaitForDeath, 5000
# # Garbage collect eventually still running process
# fWaitForDeath = () ->
# if isRunning
# test.ok false, '"testShutDown" Engine didn\'t shut down!'
# engine.kill()
# test.done()
# fs = require 'fs'
# path = require 'path'
# http = require 'http'
# needle = require 'needle'
# logger = require path.join '..', 'js-coffee', 'logging'
# log = logger.getLogger
# nolog: true
# setTimeout fWaitForStartup, 1000
# exports.testResponse = ( test ) =>
# test.expect 2
# pathFile = path.resolve 'webpages', 'public', 'style.css'
# fl = fs.readFileSync pathFile, 'utf-8'
# hl = require path.join '..', 'js-coffee', 'http-listener'
# fWaitForTestEnd = () =>
# console.log 'hl end?'
# process.kill()
# server = http.createServer()
# server.listen(0)
# server.on 'listening', () ->
# freeport = server.address().port
# server.close
# args = {
# logger: log
# }
# args[ 'http-port' ] = 8650
# hl args
# needle.get 'localhost:8650/style.css', (err, resp, body) ->
# test.ifError err, 'No response from the server'
# test.strictEqual fl, body, 'Wrong contents received'
# test.done()
# setTimeout fWaitForTestEnd, 500
# exports.testWrongPort = ( test ) =>
# test.expect 1
# hl = require path.join '..', 'js-coffee', 'http-listener'
# fWaitForTestEnd = () =>
# console.log 'hl end?'
# process.kill()
# isRunning = true
# hl.addShutdownHandler () ->
# test.ok true, 'Placeholder'
# isRunning = false
# setTimeout fWaitForTestEnd, 1000
# test.done()
# args = {
# logger: log
# }
# args[ 'http-port' ] = 8080211241
# hl args
# fWaitForInit = () ->
# test.ok !isRunning, 'Still running !?'
# if isRunning
# test.done()
# setTimeout fWaitForTestEnd, 500
# setTimeout fWaitForInit, 500
#TODO add routing tests... enjoy ;)

View file

@ -81,7 +81,12 @@ exports.testCustomPath = ( test ) =>
setTimeout fWait, 100
exports.testWrongPath = ( test ) =>
test.expect 1
empty = [
'info'
'warn'
'error'
]
test.expect empty.length
strInfo = 'TL | custom path test 1'
strPath = 'strange/path/to/test.log'
@ -89,11 +94,7 @@ exports.testWrongPath = ( test ) =>
args[ 'file-path' ] = strPath
args[ 'io-level' ] = 'error'
log = @logger.getLogger args
log.info strInfo
test.ok prop in empty, "#{ prop } shouldn't be here" for prop of log
test.done()
fWait = () =>
test.ok !fs.existsSync( path.resolve ( strPath ) ), 'Custom log file does exist!?'
test.done()
setTimeout fWait, 1000

View file

@ -17,8 +17,10 @@ exports.testShutDown = ( test ) =>
isRunning = true
pth = path.resolve 'js-coffee', 'webapi-eca'
engine = cp.fork pth, [ '-n' ] # [ '-i' , 'warn' ]
engine = cp.fork pth, [ '-n', '-w', '8640' ] # [ '-i' , 'warn' ]
engine.on 'error', ( err ) ->
console.log err
engine.on 'exit', ( code, signal ) ->
test.ok true, 'Engine stopped'
isRunning = false
@ -41,8 +43,10 @@ exports.testKill = ( test ) =>
test.expect 1
pth = path.resolve 'js-coffee', 'webapi-eca'
engine = cp.fork pth, [ '-n' ] # [ '-i' , 'warn' ]
engine = cp.fork pth, [ '-n', '-w', '8641' ] # [ '-i' , 'warn' ]
engine.on 'error', ( err ) ->
console.log err
fWaitForStartup = () ->
engine.kill()
setTimeout fWaitForDeath, 1000
@ -58,10 +62,14 @@ exports.testHttpPortAlreadyUsed = ( test ) =>
test.expect 1
isRunning = true
pth = path.resolve 'js-coffee', 'webapi-eca'
@engine_one = cp.fork pth, ['-n'] # [ '-i' , 'warn' ]
@engine_one = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
@engine_one.on 'error', ( err ) ->
console.log err
fWaitForFirstStartup = () =>
@engine_two = cp.fork pth, ['-n'] # [ '-i' , 'warn' ]
@engine_two = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
@engine_two.on 'error', ( err ) ->
console.log err
@engine_two.on 'exit', ( code, signal ) ->
test.ok true, 'Engine stopped'
@ -86,18 +94,20 @@ exports.testHttpPortInvalid = ( test ) =>
isRunning = true
pth = path.resolve 'js-coffee', 'webapi-eca'
engine = cp.fork pth, ['-n', '-w', '0'] # [ '-i' , 'warn' ]
engine = cp.fork pth, [ '-n', '-w', '1' ] # [ '-i' , 'warn' ]
engine.on 'exit', ( code, signal ) ->
test.ok true, 'Engine stopped'
isRunning = false
test.done()
engine.on 'error', ( err ) ->
console.log err
# Garbage collect eventually still running process
fWaitForDeath = () =>
engine.kill()
if isRunning
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
test.done()
# engine.kill()
setTimeout fWaitForDeath, 1000
@ -106,7 +116,9 @@ exports.testDbPortInvalid = ( test ) =>
isRunning = true
pth = path.resolve 'js-coffee', 'webapi-eca'
engine = cp.fork pth, ['-n', '-d', '10'] # [ '-i' , 'warn' ]
engine = cp.fork pth, [ '-n', '-d', '10'] # [ '-i' , 'warn' ]
engine.on 'error', ( err ) ->
console.log err
engine.on 'exit', ( code, signal ) ->
test.ok true, 'Engine stopped'
isRunning = false