blob: e4a2e9ce31c88c41be7d21abb8dc3ad3569bbc5e [file] [log] [blame]
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('goog.structs.PriorityPoolTest');
goog.setTestOnly('goog.structs.PriorityPoolTest');
goog.require('goog.structs.PriorityPool');
goog.require('goog.testing.MockClock');
goog.require('goog.testing.jsunit');
// Implementation of the Pool class with isObjectDead() always returning TRUE,
// so that the the Pool will not reuse any objects.
function NoObjectReusePriorityPool(opt_min, opt_max) {
goog.structs.PriorityPool.call(this, opt_min, opt_max);
}
goog.inherits(NoObjectReusePriorityPool, goog.structs.PriorityPool);
NoObjectReusePriorityPool.prototype.objectCanBeReused = function(obj) {
return false;
};
function testExceedMax1() {
var p = new goog.structs.PriorityPool(0, 3);
var getCount1 = 0;
var callback1 = function(obj) {
assertNotNull(obj);
getCount1++;
};
var getCount2 = 0;
var callback2 = function(obj) {
getCount2++;
};
p.getObject(callback1);
p.getObject(callback1);
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback2);
p.getObject(callback2);
assertEquals('getCount for allocated, Should be 3', getCount1, 3);
assertEquals('getCount for unallocated, Should be 0', getCount2, 0);
}
function testExceedMax2() {
var p = new goog.structs.PriorityPool(0, 1);
var getCount1 = 0;
var callback1 = function(obj) {
assertNotNull(obj);
getCount1++;
};
var getCount2 = 0;
var callback2 = function(obj) {
getCount2++;
};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback2);
p.getObject(callback2);
p.getObject(callback2);
p.getObject(callback2);
assertEquals('getCount for allocated, Should be 1', getCount1, 1);
assertEquals('getCount for unallocated, Should be 0', getCount2, 0);
}
function testExceedMax3() {
var p = new goog.structs.PriorityPool(0, 2);
var obj1 = null;
var callback1 = function(obj) {
obj1 = obj;
};
var obj2 = null;
var callback2 = function(obj) {
obj2 = obj;
};
var obj3 = null;
var callback3 = function(obj) {
obj3 = obj;
};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
assertNotNull(obj1);
assertNotNull(obj2);
assertNull(obj3);
}
function testExceedMax4() {
var p = new goog.structs.PriorityPool(); // default: 10
var objs = [];
var getCount1 = 0;
var callback1 = function(obj) {
assertNotNull(obj);
getCount1++;
};
var getCount2 = 0;
var callback2 = function(obj) {
getCount2++;
};
for (var i = 0; i < 12; i++) {
p.getObject(i < 10 ? callback1 : callback2);
}
assertEquals('getCount for allocated, Should be 10', getCount1, 10);
assertEquals('getCount for unallocated, Should be 0', getCount2, 0);
}
function testReleaseAndGet1() {
var p = new goog.structs.PriorityPool(0, 10);
var o = null;
var callback = function(obj) {
o = obj;
};
p.getObject(callback);
assertEquals(1, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertTrue('Result should be true', p.releaseObject(o));
assertEquals(1, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(1, p.getFreeCount());
}
function testReleaseAndGet2() {
var p = new NoObjectReusePriorityPool(0, 10);
var o = null;
var callback = function(obj) {
o = obj;
};
p.getObject(callback);
assertEquals(1, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertTrue('Result should be true', p.releaseObject(o));
assertEquals(0, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(0, p.getFreeCount());
}
function testReleaseAndGet3() {
var p = new goog.structs.PriorityPool(0, 10);
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
var o4 = {};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
assertEquals(3, p.getCount());
assertEquals(3, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertTrue('Result should be true', p.releaseObject(o1));
assertTrue('Result should be true', p.releaseObject(o2));
assertFalse('Result should be false', p.releaseObject(o4));
assertEquals(3, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(2, p.getFreeCount());
}
function testReleaseAndGet4() {
var p = new NoObjectReusePriorityPool(0, 10);
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
var o4 = {};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
assertEquals(3, p.getCount());
assertEquals(3, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertTrue('Result should be true', p.releaseObject(o1));
assertTrue('Result should be true', p.releaseObject(o2));
assertFalse('Result should be false', p.releaseObject(o4));
assertEquals(1, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(0, p.getFreeCount());
}
function testIsInPool1() {
var p = new goog.structs.PriorityPool();
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
var o4 = {};
var o5 = {};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
var o6 = o1;
assertTrue(p.contains(o1));
assertTrue(p.contains(o2));
assertTrue(p.contains(o3));
assertFalse(p.contains(o4));
assertFalse(p.contains(o5));
assertTrue(p.contains(o6));
}
function testSetMin1() {
var p = new goog.structs.PriorityPool(0, 10);
assertEquals(0, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(0, p.getFreeCount());
p.setMinimumCount(10);
assertEquals(10, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(10, p.getFreeCount());
}
function testSetMin2() {
var p = new goog.structs.PriorityPool(0, 10);
assertEquals(0, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(0, p.getFreeCount());
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
p.getObject(callback1);
assertEquals(1, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(0, p.getFreeCount());
p.setMinimumCount(10);
assertEquals(10, p.getCount());
assertEquals(1, p.getInUseCount());
assertEquals(9, p.getFreeCount());
}
function testSetMax1() {
var p = new goog.structs.PriorityPool(0, 10);
assertEquals(0, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(0, p.getFreeCount());
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
var o4 = null;
var callback4 = function(obj) {
o4 = obj;
};
var o5 = null;
var callback5 = function(obj) {
o5 = obj;
};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
p.getObject(callback4);
p.getObject(callback5);
assertEquals(5, p.getCount());
assertEquals(5, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertTrue('Result should be true', p.releaseObject(o5));
assertEquals(5, p.getCount());
assertEquals(4, p.getInUseCount());
assertEquals(1, p.getFreeCount());
p.setMaximumCount(4);
assertEquals(4, p.getCount());
assertEquals(4, p.getInUseCount());
assertEquals(0, p.getFreeCount());
}
function testInvalidMinMax1() {
var p = new goog.structs.PriorityPool(0, 10);
assertEquals(0, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(0, p.getFreeCount());
assertThrows(function() {
p.setMinimumCount(11);
});
}
function testInvalidMinMax2() {
var p = new goog.structs.PriorityPool(5, 10);
assertEquals(5, p.getCount());
assertEquals(0, p.getInUseCount());
assertEquals(5, p.getFreeCount());
assertThrows(function() {
p.setMaximumCount(4);
});
}
function testInvalidMinMax3() {
assertThrows(function() {
new goog.structs.PriorityPool(10, 1);
});
}
function testQueue1() {
var p = new goog.structs.PriorityPool(0, 2);
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
p.getObject(callback1);
p.getObject(callback2);
p.getObject(callback3);
assertNotNull(o1);
assertNotNull(o2);
assertNull(o3);
p.releaseObject(o1);
assertNotNull(o3);
}
function testPriority1() {
var p = new goog.structs.PriorityPool(0, 2);
var o1 = null;
var callback1 = function(obj) {
o1 = obj;
};
var o2 = null;
var callback2 = function(obj) {
o2 = obj;
};
var o3 = null;
var callback3 = function(obj) {
o3 = obj;
};
var o4 = null;
var callback4 = function(obj) {
o4 = obj;
};
var o5 = null;
var callback5 = function(obj) {
o5 = obj;
};
var o6 = null;
var callback6 = function(obj) {
o6 = obj;
};
p.getObject(callback1); // Initially seeded requests.
p.getObject(callback2);
p.getObject(callback3, 101); // Lowest priority.
p.getObject(callback4); // Second lowest priority (default is 100).
p.getObject(callback5, 99); // Second highest priority.
p.getObject(callback6, 0); // Highest priority.
assertNotNull(o1);
assertNotNull(o2);
assertNull(o3);
assertNull(o4);
assertNull(o5);
assertNull(o6);
p.releaseObject(o1); // Release the first initially seeded request (o1).
assertNotNull(o6); // Make sure the highest priority request (o6) started.
assertNull(o3);
assertNull(o4);
assertNull(o5);
p.releaseObject(o2); // Release the second, initially seeded request (o2).
assertNotNull(o5); // The second highest priority request starts (o5).
assertNull(o3);
assertNull(o4);
p.releaseObject(o6);
assertNotNull(o4);
assertNull(o3);
}
function testRateLimiting() {
var clock = new goog.testing.MockClock();
clock.install();
var p = new goog.structs.PriorityPool(0, 4);
p.setDelay(100);
var getCount = 0;
var callback = function(obj) {
assertNotNull(obj);
getCount++;
};
p.getObject(callback);
assertEquals(1, getCount);
p.getObject(callback);
assertEquals(1, getCount);
clock.tick(100);
assertEquals(2, getCount);
p.getObject(callback);
p.getObject(callback);
assertEquals(2, getCount);
clock.tick(100);
assertEquals(3, getCount);
clock.tick(100);
assertEquals(4, getCount);
p.getObject(callback);
assertEquals(4, getCount);
clock.tick(100);
assertEquals(4, getCount);
goog.dispose(clock);
}
function testRateLimitingWithChangingDelay() {
var clock = new goog.testing.MockClock();
clock.install();
var p = new goog.structs.PriorityPool(0, 3);
p.setDelay(100);
var getCount = 0;
var callback = function(obj) {
assertNotNull(obj);
getCount++;
};
p.getObject(callback);
assertEquals(1, getCount);
p.getObject(callback);
assertEquals(1, getCount);
clock.tick(50);
assertEquals(1, getCount);
p.setDelay(50);
assertEquals(2, getCount);
p.getObject(callback);
assertEquals(2, getCount);
clock.tick(20);
assertEquals(2, getCount);
p.setDelay(40);
assertEquals(2, getCount);
clock.tick(20);
assertEquals(3, getCount);
goog.dispose(clock);
}