// StatTest.js (c) 2010-2013 Loren West and other contributors
// May be freely distributed under the MIT license.
// For further details and documentation:
// http://lorenwest.github.com/monitor-min
(function(root){
// Dependencies
var Monitor = require('../lib/index'),
Stat = Monitor.Stat, Backbone = Monitor.Backbone,
stat = Monitor.getStatLogger('stat-test');
/**
* Unit tests for the <a href="Stat.html">Stat</a> class.
* @class StatTest
*/
/**
* Test group for baseline Stat functionality
*
* @method Stat
*/
module.exports['Stat'] = {
setUp: function(callback) {callback();},
tearDown: function(callback) {callback();},
/**
* Tests that Stat class is in place
* @method Stat-Classes
*/
Classes: function(test) {
test.ok(Stat.prototype, 'The Stat model is in place');
test.done();
},
/**
* Internal tests for Graphite type regular expressions
* @method Stat-GraphiteRegExp
*/
GraphiteRegExp: function(test) {
var builder = Stat._buildRegex;
var re;
// Test the normal cases
re = builder('hello.world');
test.ok(re.test('hello.world'), 'normal case works');
test.ok(!re.test('hello.wurld'), 'must be exact');
test.ok(!re.test('Hello.wurld'), 'case sensitive');
test.ok(!re.test('hello'), 'must have all words');
test.ok(!re.test('Hello.world.now'), 'limited to just the specified fields');
// Test the * wildcard
re = builder('hello.*.world');
test.ok(re.test('hello.nice.world'), 'normal case works');
test.ok(re.test('hello.cruel.world'), 'normal case works');
test.ok(!re.test('hello.cruel'), 'must have all segments');
test.ok(!re.test('hello'), 'must have all segments');
test.ok(!re.test('hello.nice.world.now'), 'too many segments');
re = builder('*.*.world');
test.ok(re.test('hello.nice.world'), 'normal case works');
test.ok(re.test('Gello.nice.world'), 'this works too');
test.ok(!re.test('Gello.nice'), 'but not this');
re = builder('*.*.*');
test.ok(re.test('a.b.c'), 'normal case works');
test.ok(re.test('1.2.3'), '123 works');
test.ok(!re.test('nice.world'), 'must have all fields');
// Test the [] character list or range
re = builder('hello.[123].world');
test.ok(re.test('hello.1.world'), '1 case works');
test.ok(re.test('hello.3.world'), '3 case works');
test.ok(!re.test('hello.4.world'), '4 doesnt work');
re = builder('hello.[1-3].world');
test.ok(re.test('hello.1.world'), '1- case works');
test.ok(re.test('hello.3.world'), '3- case works');
test.ok(!re.test('hello.4.world'), '4- doesnt work');
// Test the {list,in,str} list functionality
re = builder('hello.{world,dolly,kitty}');
test.ok(re.test('hello.world'), 'world works');
test.ok(re.test('hello.kitty'), 'kitty works');
test.ok(re.test('hello.dolly'), 'dolly works');
test.ok(!re.test('hello.there'), 'there doesnt work');
// Test the /regex/ functionality
re = builder('/hello.world/');
test.ok(re.test('hello.world'), 'hello world works');
test.ok(!re.test('hello.kitty'), 'hello kitty fails');
re = builder('/hello.world/i');
test.ok(re.test('Hello World'), 'case insensitivity training');
test.done();
},
/**
* Tests that registering for '*' emits all stats
* @method Stat-AllStats
*/
AllStats: function(test) {
// Listen for all stats
Stat.once('*', function(module, name, value, type) {
test.equals(module, 'stat-test', 'found the stat-test module when listening to *');
test.equals(name, 'Some.Stat', 'found Some.Stat when listening to *');
test.equals(value, 34, 'some.stat value is correct');
test.equals(type, 'c', 'some.stat type is correct');
test.done();
});
stat.increment('Some.Stat', 34);
},
/**
* Tests the gauge functionality
* @method Stat-Gauge
*/
Gauge: function(test) {
Stat.once('stat-test.gauge.stat', function(module, name, value, type) {
test.equals(name, 'gauge.stat', 'gauge.stat emitted correctly');
test.equals(value, -6273993, 'gauge.stat value is correct');
test.equals(type, 'g', 'gauge.stat type is correct');
test.done();
});
stat.gauge('gauge.stat', -6273993);
},
/**
* Tests the time stat
* @method Stat-Time
*/
Time: function(test) {
Stat.once('stat-test.time.stat', function(module, name, value, type) {
test.equals(name, 'time.stat', 'time.stat emitted correctly');
test.equals(value, 193, 'time.stat value is correct');
test.equals(type, 'ms', 'time.stat type is correct');
test.done();
});
stat.time('time.stat', 193);
},
/**
* Tests the increment stat
* @method Stat-Increment
*/
Increment: function(test) {
Stat.once('stat-test.incr1', function(module, name, value, type) {
test.equals(name, 'incr1', 'incr1 stat emitted');
test.equals(value, 1, 'default increment of 1 found');
test.equals(type, 'c', 'incr1 type is correct');
Stat.once('stat-test.incr2', function(module, name, value, type) {
test.equals(name, 'incr2', 'incr2 stat emitted');
test.equals(value, 44, 'incr2 value is correct');
test.equals(type, 'c', 'incr2 type is correct');
test.done();
});
stat.increment('incr2', 44);
});
stat.increment('incr1');
},
/**
* Tests the decrement stat
* @method Stat-Decrement
*/
Decrement: function(test) {
Stat.once('stat-test.decr1', function(module, name, value, type) {
test.equals(name, 'decr1', 'decr1 stat emitted');
test.equals(value, -1, 'default decrement of 1 found');
test.equals(type, 'c', 'decr1 type is correct');
Stat.once('stat-test.decr2', function(module, name, value, type) {
test.equals(name, 'decr2', 'decr2 stat emitted');
test.equals(value, -29344, 'decr2 value is correct');
test.equals(type, 'c', 'decr2 type is correct');
test.done();
});
stat.decrement('decr2', 29344);
});
stat.decrement('decr1');
},
/**
* Tests the stat probe
* @method Stat-ProbeTest
*/
ProbeTest: function(test) {
var statMonitor = new Monitor({probeClass:'Stat', initParams:{interval:10, pattern:'stat-test.*'}});
statMonitor.connect(function(error) {
test.ok(!error, 'Stat monitor error: ' + JSON.stringify(error));
statMonitor.on('change', function() {
var bundle = statMonitor.get('bundle');
// Omit the initial state of the monitor
if (bundle.length === 0) {
return;
}
test.ok(bundle, 'The stat bundle is available');
test.equals(bundle.length, 1, 'There is a single stat in the bundle');
var statArgs = bundle[0];
test.equals(statArgs.length, 4, 'There are 4 stat arguments');
test.equals(statArgs[0], 'stat-test', 'The module is correct');
test.equals(statArgs[1], 'probeTest', 'The stat name is correct');
test.equals(statArgs[2], 1, 'The value is correct');
test.equals(statArgs[3], 'c', 'There stat type is correct');
statMonitor.off('change');
test.done();
});
stat.increment('probeTest');
});
},
/**
* Tests the probe streams multiple items at once
* @method Stat-ProbeStream
*/
ProbeStream: function(test) {
// This relies on the fact that the monitor was created in the prior
// function, and it just emitted a single item.
var statMonitor = new Monitor({probeClass:'Stat', initParams:{interval:10, pattern:'stat-test.*'}});
statMonitor.connect(function(error) {
test.ok(!error, 'Stat monitor error: ' + JSON.stringify(error));
statMonitor.on('change', function() {
var bundle = statMonitor.get('bundle');
// Omit the current state of the probe (first change event)
if (bundle.length < 4) {
return;
}
test.ok(bundle, 'The stat bundle is available');
test.equals(bundle.length, 4, 'There were the correct number of items in the stream');
var statArgs = bundle[2];
test.equals(statArgs.length, 4, 'There are 4 stat arguments');
test.equals(statArgs[0], 'stat-test', 'The module is correct');
test.equals(statArgs[1], 'statGauge', 'The stat name is correct');
test.equals(statArgs[2], 420, 'The value is correct');
test.equals(statArgs[3], 'g', 'There stat type is correct');
statMonitor.off('change');
test.done();
});
stat.increment('probeTestr');
stat.decrement('probeTest');
stat.gauge('statGauge', 420);
stat.time('statTimer', 2840);
});
}
};
}(this));