Skip to content

Commit

Permalink
Bug fixes for Multiloop.getProfileTimeToNextValue_().
Browse files Browse the repository at this point in the history
  • Loading branch information
jonjlee committed Dec 14, 2010
1 parent ecca7d1 commit 425aba6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 9 deletions.
4 changes: 2 additions & 2 deletions lib/loadtesting.js
Expand Up @@ -48,9 +48,9 @@ var TEST_OPTIONS = {
requestGenerator: undefined, // 1. requestGenerator: a function
// function(http.Client) -> http.ClientRequest
requestLoop: undefined, // 2. requestLoop: is a function
// function(loopFun, http.Client)
// function(finished, http.Client)
method: 'GET', // If must call:
path: '/', // loopFun({
path: '/', // finished({
requestData: undefined, // req: http.ClientRequest,
// res: http.ClientResponse});
// after each transaction to finishes to schedule the
Expand Down
17 changes: 10 additions & 7 deletions lib/loop/multiloop.js
Expand Up @@ -83,16 +83,17 @@ MultiLoop.prototype.getProfileValue_ = function(profile, time) {
};

/** Given a profile in the format [[time, value], [time, value], ...], and the current time, return the
number of milliseconds before the profile value will change by 1. */
MultiLoop.prototype.getProfileNextTimeout_ = function(profile, time) {
time (rounded up to the nearest whole unit) before the profile value will change by 1. */
MultiLoop.prototype.getProfileTimeToNextValue_ = function(profile, time) {
if (!profile || profile.length === 0) { return Infinity; }
if (time < 0) { return -time; }

var MIN_TIMEOUT = 1000, lastval = [0,0];
var MIN_TIMEOUT = 1, lastval = [0,0];
for (var i = 0; i < profile.length; i++) {
if (profile[i][0] > time) {
var dt = profile[i][0]-lastval[0],
millisecondsPerUnitChange = dt / (profile[i][1]-lastval[1]) * 1000;
return Math.max(MIN_TIMEOUT, Math.min(dt, millisecondsPerUnitChange));
var dt = (profile[i][0]-time),
timePerUnitChange = dt / Math.abs(profile[i][1]-lastval[1]);
return Math.ceil(Math.max(MIN_TIMEOUT, Math.min(dt, timePerUnitChange)));
}
lastval = profile[i];
}
Expand All @@ -103,7 +104,9 @@ MultiLoop.prototype.update_ = function() {
var i, now = Math.floor((new Date() - this.startTime) / 1000),
concurrency = this.getProfileValue_(this.concurrencyProfile, now),
rps = this.getProfileValue_(this.rpsProfile, now),
timeout = Math.min(this.getProfileNextTimeout_(this.concurrencyProfile, now), this.getProfileNextTimeout_(this.rpsProfile, now));
timeout = Math.min(
this.getProfileTimeToNextValue_(this.concurrencyProfile, now),
this.getProfileTimeToNextValue_(this.rpsProfile, now)) * 1000;

if (concurrency < this.concurrency) {
var removed = this.loops.splice(concurrency);
Expand Down
55 changes: 55 additions & 0 deletions test/loop.test.js
Expand Up @@ -151,5 +151,60 @@ module.exports = {
assert.equal(getProfileValue(profile, 31), 250);
assert.equal(getProfileValue(profile, 32), 0);
assert.equal(getProfileValue(profile, 35), 0);
},
'test MultiLoop.getProfileTimeToNextValue_ works': function() {
var getProfileTimeToNextValue = loop.MultiLoop.prototype.getProfileTimeToNextValue_;
assert.equal(getProfileTimeToNextValue(null, 10), Infinity);
assert.equal(getProfileTimeToNextValue([], 10), Infinity);

assert.equal(getProfileTimeToNextValue([[0,10]], 0), Infinity);
assert.equal(getProfileTimeToNextValue([[0,0],[10,0]], 0), 10);
assert.equal(getProfileTimeToNextValue([[0,0],[10,100]], 0), 1);
assert.equal(getProfileTimeToNextValue([[0,0],[10,0]], 4), 6);
assert.equal(getProfileTimeToNextValue([[0,0],[10,5]], 4), 2);
assert.equal(getProfileTimeToNextValue([[0,0],[10,5]], 4.5), 2); // should round up to nearest whole number
assert.equal(getProfileTimeToNextValue([[0,0],[10,5]], 5), 1);
assert.equal(getProfileTimeToNextValue([[0,0],[10,0]], 10), Infinity);

var profile = [[0,0],[10,100],[15,100],[22,1],[30,0]];
assert.equal(getProfileTimeToNextValue(profile, -1), 1);
assert.equal(getProfileTimeToNextValue(profile, 0), 1);
assert.equal(getProfileTimeToNextValue(profile, 1), 1);
assert.equal(getProfileTimeToNextValue(profile, 1.5), 1);
assert.equal(getProfileTimeToNextValue(profile, 10), 5);
assert.equal(getProfileTimeToNextValue(profile, 13.5), 2);
assert.equal(getProfileTimeToNextValue(profile, 15), 1);
assert.equal(getProfileTimeToNextValue(profile, 21), 1);
assert.equal(getProfileTimeToNextValue(profile, 22), 8);
assert.equal(getProfileTimeToNextValue(profile, 28.5), 2);
assert.equal(getProfileTimeToNextValue(profile, 29.5), 1);
assert.equal(getProfileTimeToNextValue(profile, 30), Infinity);
},
'test MultiLoop.getProfileValue_ and MultiLoop.getProfileTimeToNextValue_ coordination': function() {
var getProfileValue = loop.MultiLoop.prototype.getProfileValue_;
var getProfileTimeToNextValue = loop.MultiLoop.prototype.getProfileTimeToNextValue_;
var profile = [[0,0],[10,100],[15,100],[22,500],[30,500],[32,0]];
assert.equal(getProfileValue(profile, 0), 0);
assert.equal(getProfileTimeToNextValue(profile, 0), 1);
assert.equal(getProfileValue(profile, 1), 10);
assert.equal(getProfileTimeToNextValue(profile, 1), 1);
assert.equal(getProfileValue(profile, 9), 90);
assert.equal(getProfileTimeToNextValue(profile, 9), 1);
assert.equal(getProfileValue(profile, 10), 100);
assert.equal(getProfileTimeToNextValue(profile, 10), 5);
assert.equal(getProfileValue(profile, 15), 100);
assert.equal(getProfileTimeToNextValue(profile, 15), 1);
assert.equal(getProfileValue(profile, 16), 157);
assert.equal(getProfileTimeToNextValue(profile, 16), 1);
assert.equal(getProfileValue(profile, 21), 442);
assert.equal(getProfileTimeToNextValue(profile, 21), 1);
assert.equal(getProfileValue(profile, 22), 500);
assert.equal(getProfileTimeToNextValue(profile, 22), 8);
assert.equal(getProfileValue(profile, 30), 500);
assert.equal(getProfileTimeToNextValue(profile, 30), 1);
assert.equal(getProfileValue(profile, 31), 250);
assert.equal(getProfileTimeToNextValue(profile, 31), 1);
assert.equal(getProfileValue(profile, 32), 0);
assert.equal(getProfileTimeToNextValue(profile, 32), Infinity);
}
};

0 comments on commit 425aba6

Please sign in to comment.