UNPKG

rackspace-shared-utils

Version:

Shared Rackspace Node.js utility modules and functions.

408 lines (332 loc) 11.1 kB
var instruments = require('../lib/instruments'); var expectedProperties = ('ops_count rate_1m rate_5m rate_15m ' + 'mean_rate min max mean_time std_dev pct_1 pct_25 ' + 'pct_75 pct_99 active errors err_rate_1m err_rate_5m ' + 'err_rate_15m err_mean_rate').split(' '); exports['test_clean_shutdown'] = function(test, assert) { var seconds = 2; var perSecond = 100; var sleepTime = 1000 / perSecond; var iterations = seconds * perSecond; var curIt = 0; var interval = setInterval(function() { instruments.measureWork('foo', 5); instruments.measureWork('bar', 10); instruments.measureWork('baz', 20); curIt += 1; if (curIt >= iterations) { clearInterval(interval); instruments.releaseWork('foo'); instruments.releaseWork('bar'); instruments.releaseWork('baz'); test.finish(); } }, sleepTime); }; exports['test_update_rates'] = function(test, assert) { var seconds = 2; var updatesPerSecond = 100; var sleepTime = 1000 / updatesPerSecond; var iterations = seconds * updatesPerSecond; var curIt = 0; var interval = null; var duration = 10; function measure() { instruments.measureWork('foo2', duration); curIt += 1; if (!interval) { interval = setInterval(measure, sleepTime); } else if (curIt >= iterations) { clearInterval(interval); assert.ok(true); var met = instruments.getWorkMetric('foo2'); instruments.releaseWork('foo2'); assert.hasProperties(met, expectedProperties, assert); assert.strictEqual(iterations, met.ops_count); assert.isWithinRange(met.mean_rate, updatesPerSecond, 6, assert); assert.strictEqual(duration, met.min); assert.strictEqual(duration, met.max); assert.strictEqual(duration, met.mean_time); assert.strictEqual(0, met.std_dev); test.finish(); } } measure(); }; exports['test_err_rates'] = function(test, assert) { var seconds = 2; var updatesPerSecond = 100; var sleepTime = 1000 / updatesPerSecond; var iterations = seconds * updatesPerSecond; var curIt = 0; var work = new instruments.Work('error_rates'); work.start(); var interval = setInterval(function() { work.stop(true); curIt += 1; if (curIt == iterations) { clearInterval(interval); var met = instruments.getWorkMetric('error_rates'); instruments.releaseWork('error_rates'); assert.hasProperties(met, expectedProperties, assert); assert.isWithinRange(met.err_mean_rate, updatesPerSecond, 6, assert); // can't test the specific minute rates because they only get updated // after 5 secs. test.finish(); } else { work = new instruments.Work('error_rates'); work.start(); } }, sleepTime); }; exports['test_get_all_metrics'] = function(test, assert) { instruments.measureWork('one', 20); instruments.measureWork('one', 40); instruments.measureWork('two', 60); var all_metrics = instruments.getWorkMetrics().reduce(function(hash, metric) { hash[metric.label] = metric; return hash; }, {}); instruments.releaseWork('one'); instruments.releaseWork('two'); assert.hasProperties(all_metrics.one, expectedProperties, assert); assert.hasProperties(all_metrics.two, expectedProperties, assert); assert.strictEqual(all_metrics.one.ops_count, 2); assert.strictEqual(all_metrics.two.ops_count, 1); test.finish(); }; exports['test_distributions'] = function(test, assert) { var data = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 100]; for (var i = 0; i < data.length; i++) { instruments.measureWork('test.distributions', data[i]); } var met = instruments.getWorkMetric('test.distributions'); instruments.releaseWork('test.distributions'); assert.hasProperties(met, expectedProperties, assert); assert.strictEqual(data.length, met.ops_count); assert.strictEqual(1, met.min); assert.strictEqual(100, met.max); // get it on. verify mean and stddev var sum = function(x, y) { return x + y; }; var mean = data.reduce(sum) / data.length; var deviations = data.map(function(x) { return x - mean;}); var stddev = Math.sqrt(deviations.map( function(x) {return x * x}).reduce(sum) / (data.length - 1)); assert.strictEqual(mean, met.mean_time); assert.strictEqual(stddev, met.std_dev); test.finish(); }; exports['test_active_counters'] = function(test, assert) { var i, work; var count = 10; var workers = []; var assertions = []; for (i = 0; i < count; i++) { work = new instruments.Work('active_counters'); work.start(); workers.push(work); } assertions.push(function(met) { return function() { assert.hasProperties(met, expectedProperties, assert); assert.strictEqual(met.active, count); }; }(instruments.getWorkMetric('active_counters'))); for (i = 0; i < count; i++) { work = workers.pop(); work.stop(); assertions.push(function(met, index) { return function() { assert.hasProperties(met, expectedProperties, assert); assert.strictEqual(met.active, count - index - 1); }; }(instruments.getWorkMetric('active_counters'), i)); } instruments.releaseWork('active_counters'); // test assertions here. assert.strictEqual(assertions.length, 11); for (var i = 0; i < assertions.length; i++) { assertions[i](); } test.finish(); }; exports['test_events'] = function(test, assert) { var i, metrics; for (i = 0; i < 10; i++) { instruments.recordEvent('foo'); } // Rates don't populate until 5 seconds, we overwrite the mean because // it changes depending on timing metrics = instruments.getEventMetrics(); metrics[0].rate_mean = 0; assert.deepEqual(metrics, [ { label: 'foo', count: 10, rate_1m: 0, rate_5m: 0, rate_15m: 0, rate_mean: 0 } ]); instruments.releaseEvent('foo'); test.finish(); }; exports['test_DummyWork'] = function(test, assert) { var work = new instruments.DummyWork('test_disabled'), key, value, count = 0; work.start(); setTimeout(function() { var met; work.stop(true); met = instruments.getWorkMetric('test_disabled'); for (key in met) { if (met.hasOwnProperty(key) && ['label', 'serializerType'].indexOf(key) === -1) { count++; value = met[key]; assert.equal(value, 0); } } assert.equal(count, Object.keys(met).length - 1); test.finish(); }, 100); }; exports['test_setGauge'] = function(test, assert) { assert.deepEqual(instruments.getGaugeMetric('foo'), { label: 'foo', value: 0 }); assert.deepEqual(instruments.getGaugeMetrics(), []); assert.deepEqual(instruments.getMetrics(), { work: [], events: [], gauges: [] }); instruments.setGauge('foo', 12); assert.deepEqual(instruments.getGaugeMetric('foo'), { label: 'foo', value: 12 }); assert.deepEqual(instruments.getGaugeMetrics(), [{label: 'foo', value: 12}]); assert.deepEqual(instruments.getMetrics(), { work: [], events: [], gauges: [{label: 'foo', value: 12}] }); instruments.shutdown(); assert.deepEqual(instruments.getGaugeMetrics(), []); test.finish(); }; exports['test_recordWork'] = function(test, assert) { var eventLabel = 'testRecordWork', finished = false, recordWork, callback = function(fin) { finished = fin; }; assert.equal(instruments.testFunctions.hasEventMetric(eventLabel), false); assert.equal(instruments.testFunctions.hasWorkMetric(eventLabel), false); recordWork = new instruments.RecordWork(eventLabel, callback); assert.ok(instruments.testFunctions.hasEventMetric(eventLabel), false); assert.ok(instruments.testFunctions.hasWorkMetric(eventLabel), false); callback = recordWork.startWork().getCallback(); assert.ok(recordWork.work.startTime); assert.strictEqual(recordWork.work.stopTime, null); setTimeout(function() { callback(true); assert.ok(finished); assert.ok(recordWork.work.stopTime); instruments.shutdown(); test.finish(); }, 100); }; exports['test_timeAsyncFunction'] = function(test, assert) { var eventLabel = 'testTimeAsyncFunction', handler = function(callback) { assert.ok(instruments.testFunctions.hasWorkMetric(eventLabel)); callback(); }, finish = function() { instruments.shutdown(); test.finish(); }; assert.equal(instruments.testFunctions.hasWorkMetric(eventLabel), false); handler = instruments.timeAsyncFunction(eventLabel, handler); assert.equal(instruments.testFunctions.hasWorkMetric(eventLabel), false); setTimeout(handler.bind(null, finish), 100); }; exports['test_runningCounter'] = function(test, assert) { var rc = new instruments.RunningGauge('rc', 42); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 42 }); assert.deepEqual(instruments.getGaugeMetrics(), [{ label: 'rc', value: 42 }]); rc.incr(); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 43 }); rc.incr(42); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 85 }); rc.incr(0); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 85 }); rc.decr(20); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 65 }); rc.decr(); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 64 }); rc.decr(0); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 64 }); rc.reset(); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 42 }); rc.reset(10); assert.deepEqual(instruments.getGaugeMetric('rc'), { label: 'rc', value: 10 }); test.finish(); }; exports['test_find_metrics'] = function(test, assert) { /* Testing findGauges */ instruments.setGauge('foo.bar.tex', 12); instruments.setGauge('foo.bike.tex', 13); assert.deepEqual(instruments.findGaugeMetrics('foo.*'), ['foo.bar.tex', 'foo.bike.tex']); assert.deepEqual(instruments.findGaugeMetrics('foo.*.tex'), ['foo.bar.tex', 'foo.bike.tex']); assert.deepEqual(instruments.findGaugeMetrics('foo.bar.*'), ['foo.bar.tex']); /* Testing findEvents */ instruments.recordEvent('test.event.1'); instruments.recordEvent('test.event.2'); instruments.recordEvent('test.event'); assert.deepEqual(instruments.findEventMetrics('test.event'), ['test.event']); assert.deepEqual(instruments.findEventMetrics('test.event.*'), ['test.event.1', 'test.event.2', 'test.event']); /* Testing findWorks */ instruments.measureWork('test1.work.1', 10); instruments.measureWork('test2.work.2', 11); instruments.measureWork('test3.work', 7); assert.deepEqual(instruments.findWorkMetrics('*.*.2'), ['test2.work.2']); assert.deepEqual(instruments.findWorkMetrics('*.work.*'), ['test1.work.1', 'test2.work.2', 'test3.work']); instruments.shutdown(); test.finish(); };