From 64f965d74374f3a15342bf6e807ac50513a69f68 Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Wed, 25 Aug 2010 22:20:41 +0100 Subject: Add a test for query timerange --- jarmon/jarmon.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 44c4dad..6296fc5 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -27,6 +27,7 @@ if(typeof jarmon == 'undefined') { var jarmon = {}; } + jarmon.downloadBinary = function(url) { /** * Download a binary file asynchronously using the jQuery.ajax function @@ -126,6 +127,20 @@ jarmon.localTimeFormatter = function (v, axis) { }; +jarmon.TimeRangeError = function(message) { + /** + * Raised when an invalid timerange is encountered. + * + * @class jarmon.TimeRangeError + * @constructor + * @param message {String} A description of the error reason + **/ + this.name = "TimeRangeError"; + this.message = (message || ""); +} +jarmon.TimeRangeError.prototype = Error.prototype; + + /** * A wrapper around an instance of javascriptrrd.RRDFile which provides a * convenient way to query the RRDFile based on time range, RRD data source (DS) @@ -156,6 +171,14 @@ jarmon.RrdQuery.prototype.getData = function(startTime, endTime, dsId, cfName) { * @return {Object} A Flot compatible data series * eg label: '', data: [], unit: '' **/ + + if (startTime >= endTime) { + throw new jarmon.TimeRangeError( + ['starttime must be less than endtime. ', + 'starttime: ', starttime, + 'endtime: ', endtime].join('')); + } + var startTimestamp = startTime/1000; var lastUpdated = this.rrd.getLastUpdate(); -- cgit v1.2.3 From 333dfba10d99e5a2eec391c2481156329e2949dc Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Sat, 28 Aug 2010 22:34:26 +0100 Subject: the start of a builder of simple, testable rrd files --- jarmon/jarmon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 6296fc5..24f967d 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -263,7 +263,7 @@ jarmon.RrdQuery.prototype.getData = function(startTime, endTime, dsId, cfName) { jarmon.RrdQueryRemote = function(url, unit, downloader) { this.url = url; this.unit = unit; - this.downloader = downloader; + this.downloader = downloader || jarmon.downloadBinary; this.lastUpdate = 0; this._download = null; }; -- cgit v1.2.3 From 047d284b792ce7ac2b8e47e8067b142c5f081ee7 Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Mon, 30 Aug 2010 22:02:51 +0100 Subject: hopefully more consistent behaviour - more like rrdtool fetch --- jarmon/jarmon.js | 71 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 24f967d..ed26702 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -156,15 +156,15 @@ jarmon.RrdQuery = function(rrd, unit) { this.unit = unit; }; -jarmon.RrdQuery.prototype.getData = function(startTime, endTime, dsId, cfName) { +jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfName) { /** * Generate a Flot compatible data object containing rows between start and * end time. The rows are taken from the first RRA whose data spans the * requested time range. * * @method getData - * @param startTime {Number} start timestamp - * @param endTime {Number} end timestamp + * @param startTimeJs {Number} start timestamp in microseconds + * @param endTimeJs {Number} end timestamp in microseconds * @param dsId {Variant} identifier of the RRD datasource (string or number) * @param cfName {String} The name of an RRD consolidation function (CF) * eg AVERAGE, MIN, MAX @@ -172,22 +172,31 @@ jarmon.RrdQuery.prototype.getData = function(startTime, endTime, dsId, cfName) { * eg label: '', data: [], unit: '' **/ - if (startTime >= endTime) { + if (startTimeJs >= endTimeJs) { throw new jarmon.TimeRangeError( ['starttime must be less than endtime. ', - 'starttime: ', starttime, - 'endtime: ', endtime].join('')); + 'starttime: ', startTimeJs, + 'endtime: ', endTimeJs].join('')); } - var startTimestamp = startTime/1000; - + // The startTime, endTime and lastupdate time are not necessarily on a step + // boundaries. Here we divide, round and then multiply by the step size to + // find the nearest "Primary Data Point" (PDP) time. + var minStep = this.rrd.getMinStep(); + var startTime = Math.round(startTimeJs/1000/minStep) * minStep; var lastUpdated = this.rrd.getLastUpdate(); - var endTimestamp = lastUpdated; - if(endTime) { - endTimestamp = endTime/1000; + var lastPdpTime = Math.round(lastUpdated / minStep) * minStep; + + var endTime = lastPdpTime; + if(endTimeJs) { + endTime = endTimeJs/1000; // If end time stamp is beyond the range of this rrd then reset it - if(lastUpdated < endTimestamp) { - endTimestamp = lastUpdated; + // XXX: Is this the correct behaviour. Perhaps better to throw exception + // or simply return nan for each missing PDP - like rrdtool fetch. + if(lastPdpTime < endTime) { + endTime = lastPdpTime; + } else { + endTime = Math.round(endTime / minStep) * minStep; } } @@ -200,7 +209,7 @@ jarmon.RrdQuery.prototype.getData = function(startTime, endTime, dsId, cfName) { cfName = 'AVERAGE'; } - var rra, step, rraRowCount, firstUpdated; + var rra, step, rraRowCount, firstPdpTime; for(var i=0; i Date: Mon, 30 Aug 2010 23:50:34 +0100 Subject: Properly calculate the index of first result row --- jarmon/jarmon.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index ed26702..32e0283 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -190,14 +190,6 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam var endTime = lastPdpTime; if(endTimeJs) { endTime = endTimeJs/1000; - // If end time stamp is beyond the range of this rrd then reset it - // XXX: Is this the correct behaviour. Perhaps better to throw exception - // or simply return nan for each missing PDP - like rrdtool fetch. - if(lastPdpTime < endTime) { - endTime = lastPdpTime; - } else { - endTime = Math.round(endTime / minStep) * minStep; - } } if(dsId == null) { @@ -209,7 +201,7 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam cfName = 'AVERAGE'; } - var rra, step, rraRowCount, firstPdpTime; + var rra, step, rraRowCount, lastRowTime, firstRowTime; for(var i=0; i Date: Thu, 2 Sep 2010 23:52:25 +0100 Subject: Add test for unknown consolidation function error --- jarmon/jarmon.js | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 32e0283..3f63b3e 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -127,20 +127,6 @@ jarmon.localTimeFormatter = function (v, axis) { }; -jarmon.TimeRangeError = function(message) { - /** - * Raised when an invalid timerange is encountered. - * - * @class jarmon.TimeRangeError - * @constructor - * @param message {String} A description of the error reason - **/ - this.name = "TimeRangeError"; - this.message = (message || ""); -} -jarmon.TimeRangeError.prototype = Error.prototype; - - /** * A wrapper around an instance of javascriptrrd.RRDFile which provides a * convenient way to query the RRDFile based on time range, RRD data source (DS) @@ -173,7 +159,7 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam **/ if (startTimeJs >= endTimeJs) { - throw new jarmon.TimeRangeError( + throw RangeError( ['starttime must be less than endtime. ', 'starttime: ', startTimeJs, 'endtime: ', endTimeJs].join('')); @@ -182,6 +168,7 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam // The startTime, endTime and lastupdate time are not necessarily on a step // boundaries. Here we divide, round and then multiply by the step size to // find the nearest "Primary Data Point" (PDP) time. + console.log('RRD: ', this.rrd); var minStep = this.rrd.getMinStep(); var startTime = Math.round(startTimeJs/1000/minStep) * minStep; var lastUpdated = this.rrd.getLastUpdate(); @@ -229,7 +216,7 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam // If we got to the end of the loop without ever defining step, it means // that the CF check never succeded. if(!step) { - throw new Error('Unrecognised consolidation function: ' + cfName); + throw TypeError('Unrecognised consolidation function: ' + cfName); } var startRowTime = Math.floor(startTime/step)*step + step; -- cgit v1.2.3 From e9b1a0b4728d9e74ae3c6dccbf037e07f36f5fd4 Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Sun, 3 Oct 2010 20:57:16 +0100 Subject: More complete tests for getData and associated simplification of the getData code. --- jarmon/jarmon.js | 56 ++++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 34 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 3f63b3e..6ac410c 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -165,16 +165,11 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam 'endtime: ', endTimeJs].join('')); } - // The startTime, endTime and lastupdate time are not necessarily on a step - // boundaries. Here we divide, round and then multiply by the step size to - // find the nearest "Primary Data Point" (PDP) time. - console.log('RRD: ', this.rrd); - var minStep = this.rrd.getMinStep(); - var startTime = Math.round(startTimeJs/1000/minStep) * minStep; + var startTime = startTimeJs/1000; var lastUpdated = this.rrd.getLastUpdate(); - var lastPdpTime = Math.round(lastUpdated / minStep) * minStep; - var endTime = lastPdpTime; + // default endTime to the last updated time (quantized to rrd step boundry) + var endTime = lastUpdated - lastUpdated%this.rrd.getMinStep(); if(endTimeJs) { endTime = endTimeJs/1000; } @@ -202,8 +197,7 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam step = rra.getStep(); rraRowCount = rra.getNrRows(); - - lastRowTime = Math.round(lastUpdated/step)*step; + lastRowTime = lastUpdated-lastUpdated%step; firstRowTime = lastRowTime - rraRowCount * step; // We assume that the RRAs are listed in ascending order of time range, @@ -219,36 +213,30 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam throw TypeError('Unrecognised consolidation function: ' + cfName); } - var startRowTime = Math.floor(startTime/step)*step + step; - var endRowTime = Math.floor(endTime/step)*step + step; - var flotData = []; - var timestamp = startRowTime; + var dsIndex = ds.getIdx(); - // Fill in any blank values at the start of the query, before we reach the - // first data in the chosen RRA - while(timestamp<=endRowTime && timestamp Date: Mon, 4 Oct 2010 00:54:48 +0100 Subject: Add an error placeholder instead of replacing entire template content with error message - preventing subsequent chart rendering. --- jarmon/jarmon.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 6ac410c..06ec4c8 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -521,6 +521,9 @@ jarmon.Chart.prototype.draw = function() { return MochiKit.Async.gatherResults(results) .addCallback( function(self, data) { + // Clear any previous error messages. + self.template.find('.error').empty().hide(); + var i, label, disabled = []; unit = ''; for(i=0; i').text(self.siPrefix + unit) .css({width: '100px', @@ -556,7 +559,7 @@ jarmon.Chart.prototype.draw = function() { // table is useful as it generates an optimum label element // width which we can copy to the new divs + a little extra // to accomodate the color box - var legend = self.template.find('.graph-legend'); + var legend = self.template.find('.graph-legend').show(); legend.empty(); self.template.find('.legendLabel') .each(function(i, el) { @@ -585,7 +588,10 @@ jarmon.Chart.prototype.draw = function() { }, this) .addErrback( function(self, failure) { - self.template.text('error: ' + failure.message); + self.template.find('.chart').empty().hide(); + self.template.find('.graph-legend').empty().hide(); + self.template.find('.error').text('error: ' + failure.message); + }, this) .addBoth( function(self, res) { -- cgit v1.2.3 From b0d9466ca1f987775c75cdf68607a0ae19a772ca Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Mon, 4 Oct 2010 23:59:04 +0100 Subject: add caps on the start and end times in rrd query --- jarmon/jarmon.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'jarmon/jarmon.js') diff --git a/jarmon/jarmon.js b/jarmon/jarmon.js index 06ec4c8..406c4d1 100644 --- a/jarmon/jarmon.js +++ b/jarmon/jarmon.js @@ -216,14 +216,21 @@ jarmon.RrdQuery.prototype.getData = function(startTimeJs, endTimeJs, dsId, cfNam var flotData = []; var dsIndex = ds.getIdx(); - var startRowTime = startTime - startTime%step; - var endRowTime = endTime - endTime%step; - - //console.log('FRT: ', new Date(startRowTime*1000)); - //console.log('ERT: ', new Date(endRowTime*1000)); - //console.log('LRT: ', new Date(lastRowTime*1000)); - //console.log('DIFF: ', (lastRowTime - startRowTime) / step); - //console.log('ROWS: ', rraRowCount); + var startRowTime = Math.max(firstRowTime, startTime - startTime%step); + var endRowTime = Math.min(lastRowTime, endTime - endTime%step); + // If RRD exists, but hasn't been updated then the start time might end up + // being higher than the end time (which is capped at the last row time of + // the chosen RRA, so cap startTime at endTime...if you see what I mean) + startRowTime = Math.min(startRowTime, endRowTime); + + /* + console.log('FRT: ', new Date(firstRowTime*1000)); + console.log('LRT: ', new Date(lastRowTime*1000)); + console.log('SRT: ', new Date(startRowTime*1000)); + console.log('ERT: ', new Date(endRowTime*1000)); + console.log('DIFF: ', (lastRowTime - startRowTime) / step); + console.log('ROWS: ', rraRowCount); + */ var startRowIndex = rraRowCount - (lastRowTime - startRowTime) / step; var endRowIndex = rraRowCount - (lastRowTime - endRowTime) / step; -- cgit v1.2.3