mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-24 12:13:33 +08:00
395 lines
15 KiB
JavaScript
395 lines
15 KiB
JavaScript
// This file isn't really testing anything useful yet, it is just testing
|
|
// (or demonstrating) qunit+backbone interactions.
|
|
define([
|
|
"utils/metrics-logger",
|
|
"jquery",
|
|
"sinon-qunit"
|
|
], function(
|
|
metrics,
|
|
$,
|
|
sinon
|
|
){
|
|
/*globals equal test module expect deepEqual strictEqual throws ok */
|
|
"use strict";
|
|
|
|
var MockConsole = function(){
|
|
var self = this;
|
|
self.lastMessage = null;
|
|
[ 'log', 'debug', 'info', 'warn', 'error' ].forEach( function( fnName ){
|
|
self[ fnName ] = function(){
|
|
var args = Array.prototype.slice.call( arguments, 0 );
|
|
//console.debug( 'MockConsole:', fnName, JSON.stringify( args ) );
|
|
self.lastMessage = { level: fnName, args: args };
|
|
};
|
|
});
|
|
return self;
|
|
};
|
|
|
|
var MockLocalStorage = function(){
|
|
var self = this;
|
|
self._storage = {};
|
|
self.setItem = function( k, v ){
|
|
self._storage[ k ] = v + '';
|
|
return undefined;
|
|
};
|
|
self.getItem = function( k ){
|
|
return self._storage.hasOwnProperty( k )? self._storage[ k ]: null;
|
|
};
|
|
self.removeItem = function( k ){
|
|
if( self._storage.hasOwnProperty( k ) ){
|
|
delete self._storage[ k ];
|
|
}
|
|
return undefined;
|
|
};
|
|
self.key = function( i ){
|
|
var index = 0;
|
|
for( var k in self._storage ){
|
|
if( self._storage.hasOwnProperty( k ) ){
|
|
if( i === index ){ return k; }
|
|
index += 1;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
self.clear = function(){
|
|
self._storage = {};
|
|
};
|
|
// property - not worth it
|
|
//self.length = function(){};
|
|
|
|
return self;
|
|
};
|
|
window.localStorage = new MockLocalStorage();
|
|
|
|
( window.bootstrapped = {} ).user = {
|
|
id : 'test'
|
|
};
|
|
|
|
module( "Metrics logger tests" );
|
|
// ======================================================================== MetricsLogger
|
|
test( "logger construction/initializiation defaults", function() {
|
|
var logger = new metrics.MetricsLogger({});
|
|
equal( logger.consoleLogger, null );
|
|
equal( logger.options.logLevel, metrics.MetricsLogger.NONE );
|
|
equal( logger.options.consoleLevel, metrics.MetricsLogger.NONE );
|
|
equal( logger.options.defaultNamespace, 'Galaxy' );
|
|
equal( logger.options.clientPrefix, 'client.' );
|
|
equal( logger.options.postSize, 1000 );
|
|
equal( logger.options.maxCacheSize, 3000 );
|
|
equal( logger.options.addTime, true );
|
|
equal( logger.options.postUrl, '/api/metrics' );
|
|
equal( logger.options.getPingData, undefined );
|
|
equal( logger.options.onServerResponse, undefined );
|
|
|
|
equal( logger._postSize, 1000 );
|
|
equal( logger.cache.constructor, metrics.LoggingCache );
|
|
});
|
|
|
|
test( "_parseLevel", function() {
|
|
var logger = new metrics.MetricsLogger({});
|
|
equal( logger._parseLevel( 'all' ), metrics.MetricsLogger.ALL );
|
|
equal( logger._parseLevel( 'debug' ), metrics.MetricsLogger.DEBUG );
|
|
equal( logger._parseLevel( 'info' ), metrics.MetricsLogger.INFO );
|
|
equal( logger._parseLevel( 'warn' ), metrics.MetricsLogger.WARN );
|
|
equal( logger._parseLevel( 'error' ), metrics.MetricsLogger.ERROR );
|
|
equal( logger._parseLevel( 'metric' ), metrics.MetricsLogger.METRIC );
|
|
equal( logger._parseLevel( 'none' ), metrics.MetricsLogger.NONE );
|
|
equal( logger._parseLevel( 15 ), 15 );
|
|
|
|
throws( function(){
|
|
logger._parseLevel( undefined );
|
|
}, /Unknown log level/, 'Unknown log level throws error' );
|
|
throws( function(){
|
|
logger._parseLevel( 'nope' );
|
|
}, /Unknown log level/, 'Unknown log level throws error' );
|
|
});
|
|
|
|
// ------------------------------------------------------------------------ Emit to cache
|
|
test( "emit to cache at level", function() {
|
|
var logger = new metrics.MetricsLogger({
|
|
logLevel : 'metric'
|
|
});
|
|
logger.cache.empty();
|
|
|
|
equal( logger.options.logLevel, metrics.MetricsLogger.METRIC );
|
|
logger.emit( 'metric', 'test', [ 1, 2, { three: 3 }] );
|
|
equal( logger.cache.length(), 1 );
|
|
|
|
var cached = logger.cache.get( 1 )[0];
|
|
//console.debug( 'cached:', JSON.stringify( cached ) );
|
|
equal( cached.level, metrics.MetricsLogger.METRIC );
|
|
equal( cached.namespace, 'client.test' );
|
|
equal( cached.args.length, 3 );
|
|
equal( cached.args[2].three, 3 );
|
|
ok( typeof cached.time === 'string' );
|
|
ok( cached.time === new Date( cached.time ).toISOString() );
|
|
});
|
|
|
|
test( "emit to cache below does not cache", function() {
|
|
var logger = new metrics.MetricsLogger({
|
|
logLevel : 'metric'
|
|
});
|
|
logger.cache.empty();
|
|
|
|
logger.emit( 'error', 'test', [ 1, 2, { three: 3 }] );
|
|
equal( logger.cache.length(), 0 );
|
|
});
|
|
|
|
test( "emit to cache (silently) drops non-parsable", function() {
|
|
var logger = new metrics.MetricsLogger({
|
|
logLevel : 'metric'
|
|
});
|
|
logger.cache.empty();
|
|
|
|
logger.emit( 'metric', 'test', [{ window: window }] );
|
|
equal( logger.cache.length(), 0 );
|
|
});
|
|
|
|
function metricsFromRequestBody( request ){
|
|
// assumes 'metrics' is only entry in requestBody
|
|
return JSON.parse( decodeURIComponent( request.requestBody.replace( 'metrics=', '' ) ) );
|
|
}
|
|
|
|
test( "_postCache success", function () {
|
|
var callback = sinon.spy(),
|
|
logger = new metrics.MetricsLogger({
|
|
logLevel : 'metric',
|
|
onServerResponse : function( response ){ callback(); }
|
|
});
|
|
logger.cache.empty();
|
|
|
|
var server = sinon.fakeServer.create(),
|
|
metricsOnServer;
|
|
server.respondWith( 'POST', '/api/metrics', function( request ){
|
|
metricsOnServer = metricsFromRequestBody( request );
|
|
//console.debug( 'requestBody:', request.requestBody );
|
|
//console.debug( 'metricsOnServer:', JSON.stringify( metricsOnServer, null, ' ' ) );
|
|
request.respond(
|
|
200,
|
|
{ "Content-Type": "application/json" },
|
|
JSON.stringify({
|
|
fakeResponse: 'yes'
|
|
})
|
|
);
|
|
});
|
|
|
|
logger.emit( 'metric', 'test', [ 1, 2, { three: 3 }] );
|
|
logger._postCache();
|
|
server.respond();
|
|
|
|
ok( callback.calledOnce, 'onServerResponse was called' );
|
|
equal( logger.cache.length(), 0, 'should have emptied cache (on success)' );
|
|
equal( logger._postSize, 1000, '_postSize still at default' );
|
|
|
|
// metrics were in proper form on server
|
|
equal( metricsOnServer.length, 1 );
|
|
var metric = metricsOnServer[0];
|
|
equal( metric.level, metrics.MetricsLogger.METRIC );
|
|
equal( metric.namespace, 'client.test' );
|
|
equal( metric.args.length, 3 );
|
|
equal( metric.args[2].three, 3 );
|
|
ok( typeof metric.time === 'string' );
|
|
ok( metric.time === new Date( metric.time ).toISOString() );
|
|
|
|
server.restore();
|
|
});
|
|
|
|
test( "_postCache failure", function () {
|
|
var callback = sinon.spy(),
|
|
logger = new metrics.MetricsLogger({
|
|
logLevel : 'metric',
|
|
onServerResponse : function( response ){ callback(); }
|
|
});
|
|
logger.cache.empty();
|
|
|
|
var server = sinon.fakeServer.create();
|
|
server.respondWith( 'POST', '/api/metrics', function( request ){
|
|
request.respond(
|
|
500,
|
|
{ "Content-Type": "application/json" },
|
|
JSON.stringify({
|
|
err_msg: 'NoooOPE!'
|
|
})
|
|
);
|
|
});
|
|
|
|
logger.emit( 'metric', 'test', [ 1, 2, { three: 3 }] );
|
|
logger._postCache();
|
|
server.respond();
|
|
//TODO: is the following what we want?
|
|
ok( !callback.calledOnce, 'onServerResponse was NOT called' );
|
|
equal( logger.cache.length(), 1, 'should NOT have emptied cache' );
|
|
equal( logger._postSize, logger.options.maxCacheSize, '_postSize changed to max' );
|
|
|
|
server.restore();
|
|
});
|
|
|
|
// ------------------------------------------------------------------------ Emit to console
|
|
test( "emit to console at level", function() {
|
|
var mockConsole = new MockConsole(),
|
|
logger = new metrics.MetricsLogger({
|
|
consoleLevel : 'debug',
|
|
consoleLogger : mockConsole
|
|
});
|
|
equal( logger.options.consoleLevel, metrics.MetricsLogger.DEBUG );
|
|
equal( logger.consoleLogger.constructor, MockConsole );
|
|
|
|
logger.emit( 'debug', 'test', [ 1, 2, { three: 3 }] );
|
|
equal( logger.cache.length(), 0 );
|
|
//console.debug( JSON.stringify( mockConsole.lastMessage ) );
|
|
equal( mockConsole.lastMessage.level, 'debug' );
|
|
equal( mockConsole.lastMessage.args.length, 4 );
|
|
equal( mockConsole.lastMessage.args[0], 'test' );
|
|
equal( mockConsole.lastMessage.args[3].three, 3 );
|
|
});
|
|
|
|
test( "emit to console below does not output", function() {
|
|
var mockConsole = new MockConsole(),
|
|
logger = new metrics.MetricsLogger({
|
|
consoleLevel : 'error',
|
|
consoleLogger : mockConsole
|
|
});
|
|
logger.emit( 'debug', 'test', [ 1, 2, { three: 3 }] );
|
|
equal( mockConsole.lastMessage, null );
|
|
});
|
|
|
|
// ------------------------------------------------------------------------ Shortcuts
|
|
test( "logger shortcuts emit to default namespace properly", function() {
|
|
var logger = new metrics.MetricsLogger({
|
|
logLevel : 'all'
|
|
});
|
|
logger.cache.empty();
|
|
|
|
equal( logger.options.logLevel, metrics.MetricsLogger.ALL );
|
|
logger.log( 0 );
|
|
logger.debug( 1 );
|
|
logger.info( 2 );
|
|
logger.warn( 3 );
|
|
logger.error( 4 );
|
|
logger.metric( 5 );
|
|
|
|
equal( logger.cache.length(), 6 );
|
|
var cached = logger.cache.remove( 6 ),
|
|
entry;
|
|
|
|
cached.forEach( function( entry ){
|
|
ok( entry.namespace === logger.options.clientPrefix + logger.options.defaultNamespace );
|
|
ok( jQuery.type( entry.args ) === 'array' );
|
|
ok( typeof entry.time === 'string' );
|
|
});
|
|
|
|
// log is different
|
|
entry = cached[0];
|
|
ok( entry.level === 1 );
|
|
ok( entry.args[0] === 0 );
|
|
|
|
[ 'debug', 'info', 'warn', 'error', 'metric' ].forEach( function( level, i ){
|
|
entry = cached[( i + 1 )];
|
|
ok( entry.level === logger._parseLevel( level ) );
|
|
ok( entry.args[0] === ( i + 1 ) );
|
|
});
|
|
});
|
|
|
|
|
|
// ======================================================================== LoggingCache
|
|
test( "cache construction/initializiation defaults", function() {
|
|
// use empty to prevent tests stepping on one another due to persistence
|
|
var cache = new metrics.LoggingCache({ key: 'logs-test' }).empty();
|
|
equal( cache.maxSize, 5000 );
|
|
equal( window.localStorage.getItem( 'logs-test' ), '[]' );
|
|
});
|
|
|
|
test( "cache construction/initializiation failure", function() {
|
|
////TODO: doesn't work - readonly
|
|
//window.localStorage = null;
|
|
//console.debug( 'localStorage:', window.localStorage );
|
|
var oldFn = metrics.LoggingCache.prototype._hasStorage;
|
|
metrics.LoggingCache.prototype._hasStorage = function(){ return false; };
|
|
throws( function(){
|
|
return new metrics.LoggingCache({ key: 'logs-test' });
|
|
}, /LoggingCache needs localStorage/, 'lack of localStorage throws error' );
|
|
metrics.LoggingCache.prototype._hasStorage = oldFn;
|
|
|
|
throws( function(){
|
|
return new metrics.LoggingCache();
|
|
}, /LoggingCache needs key for localStorage/, 'lack of key throws error' );
|
|
});
|
|
|
|
test( "cache construction/initializiation setting max cache size", function() {
|
|
var cache = new metrics.LoggingCache({
|
|
key : 'logs-test',
|
|
maxSize : 5
|
|
}).empty();
|
|
equal( cache.maxSize, 5 );
|
|
});
|
|
|
|
test( "cache plays well with no data", function() {
|
|
var cache = new metrics.LoggingCache({ key: 'logs-test' }).empty();
|
|
|
|
equal( cache.length(), 0 );
|
|
var get = cache.get( 10 );
|
|
ok( jQuery.type( get ) === 'array' && get.length === 0 );
|
|
var remove = cache.remove( 10 );
|
|
ok( jQuery.type( remove ) === 'array' && remove.length === 0 );
|
|
equal( cache.length(), 0 );
|
|
});
|
|
|
|
test( "cache add properly adds and removes data", function() {
|
|
var cache = new metrics.LoggingCache({
|
|
key : 'logs-test',
|
|
maxSize : 5
|
|
}).empty();
|
|
|
|
var entry1 = [{ one: 1 }, 'two' ];
|
|
cache.add( entry1 );
|
|
|
|
equal( cache.length(), 1 );
|
|
equal( JSON.stringify( cache.get( 1 )[0] ), JSON.stringify( entry1 ) );
|
|
|
|
var entry2 = { blah: { one: 1 }, bler: [ 'three', { two: 2 } ] };
|
|
cache.add( entry2 );
|
|
equal( cache.length(), 2 );
|
|
equal( cache.stringify( 2 ), '[' + JSON.stringify( entry1 ) + ',' + JSON.stringify( entry2 ) + ']' );
|
|
|
|
// FIFO
|
|
var returned = cache.remove( 1 );
|
|
equal( cache.length(), 1 );
|
|
ok( jQuery.type( returned ) === 'array' && returned.length === 1 );
|
|
var returned0 = returned[0];
|
|
ok( jQuery.type( returned0 ) === 'array' && JSON.stringify( returned0 ) === JSON.stringify( entry1 ) );
|
|
});
|
|
|
|
test( "cache past max loses oldest", function() {
|
|
var cache = new metrics.LoggingCache({
|
|
key : 'logs-test',
|
|
maxSize : 5
|
|
}).empty();
|
|
|
|
for( var i=0; i<10; i+=1 ){
|
|
cache.add({ index: i });
|
|
}
|
|
equal( cache.length(), 5 );
|
|
var get = cache.get( 5 );
|
|
ok( get[0].index === 5 );
|
|
ok( get[1].index === 6 );
|
|
ok( get[2].index === 7 );
|
|
ok( get[3].index === 8 );
|
|
ok( get[4].index === 9 );
|
|
});
|
|
|
|
test( "cache is properly persistent", function() {
|
|
var cache1 = new metrics.LoggingCache({ key : 'logs-test' }).empty(),
|
|
entry = [{ one: 1 }, 'two' ];
|
|
cache1.add( entry );
|
|
equal( cache1.length(), 1 );
|
|
|
|
var cache2 = new metrics.LoggingCache({ key : 'logs-test' });
|
|
equal( cache2.length(), 1, 'old key gets previously stored' );
|
|
equal( JSON.stringify( cache2.get( 1 )[0] ), JSON.stringify( entry ) );
|
|
|
|
var cache3 = new metrics.LoggingCache({ key : 'logs-bler' });
|
|
equal( cache3.length(), 0, 'new key causes new storage' );
|
|
});
|
|
|
|
});
|