Update app and tooling
This commit is contained in:
parent
3046531bdd
commit
e620ec7349
4950 changed files with 2975120 additions and 10 deletions
144
node_modules/generic-pool/test/doubly-linked-list-iterator-test.js
generated
vendored
Normal file
144
node_modules/generic-pool/test/doubly-linked-list-iterator-test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
const tap = require("tap");
|
||||
const DLL = require("../lib/DoublyLinkedList");
|
||||
const Iterator = require("../lib/DoublyLinkedListIterator");
|
||||
|
||||
tap.test("iterates forward", function(t) {
|
||||
const dll = new DLL();
|
||||
|
||||
const node1 = DLL.createNode({ id: 1 });
|
||||
const node2 = DLL.createNode({ id: 2 });
|
||||
const node3 = DLL.createNode({ id: 3 });
|
||||
const node4 = DLL.createNode({ id: 4 });
|
||||
|
||||
dll.insertBeginning(node1);
|
||||
dll.insertBeginning(node2);
|
||||
dll.insertBeginning(node3);
|
||||
dll.insertBeginning(node4);
|
||||
|
||||
const iterator = new Iterator(dll);
|
||||
|
||||
const iterationResult1 = iterator.next();
|
||||
t.notOk(iterationResult1.done);
|
||||
t.same(iterationResult1.value, node4);
|
||||
|
||||
iterator.next();
|
||||
iterator.next();
|
||||
|
||||
const iterationResult4 = iterator.next();
|
||||
t.notOk(iterationResult4.done);
|
||||
t.same(iterationResult4.value, node1);
|
||||
|
||||
const iterationResult5 = iterator.next();
|
||||
t.ok(iterationResult5.done);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("iterates backwards", function(t) {
|
||||
const dll = new DLL();
|
||||
|
||||
const node1 = DLL.createNode({ id: 1 });
|
||||
const node2 = DLL.createNode({ id: 2 });
|
||||
const node3 = DLL.createNode({ id: 3 });
|
||||
const node4 = DLL.createNode({ id: 4 });
|
||||
|
||||
dll.insertBeginning(node1);
|
||||
dll.insertBeginning(node2);
|
||||
dll.insertBeginning(node3);
|
||||
dll.insertBeginning(node4);
|
||||
|
||||
const iterator = new Iterator(dll, true);
|
||||
|
||||
const iterationResult1 = iterator.next();
|
||||
t.notOk(iterationResult1.done);
|
||||
t.same(iterationResult1.value, node1);
|
||||
|
||||
iterator.next();
|
||||
iterator.next();
|
||||
|
||||
const iterationResult4 = iterator.next();
|
||||
t.notOk(iterationResult4.done);
|
||||
t.same(iterationResult4.value, node4);
|
||||
|
||||
const iterationResult5 = iterator.next();
|
||||
t.ok(iterationResult5.done);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("iterates forward when adding nodes after creating iterator", function(
|
||||
t
|
||||
) {
|
||||
const dll = new DLL();
|
||||
|
||||
const node1 = DLL.createNode({ id: 1 });
|
||||
const node2 = DLL.createNode({ id: 2 });
|
||||
|
||||
const iterator = new Iterator(dll);
|
||||
|
||||
dll.insertBeginning(node1);
|
||||
dll.insertBeginning(node2);
|
||||
|
||||
const iterationResult1 = iterator.next();
|
||||
t.notOk(iterationResult1.done);
|
||||
t.same(iterationResult1.value, node2);
|
||||
|
||||
const iterationResult2 = iterator.next();
|
||||
t.notOk(iterationResult2.done);
|
||||
t.same(iterationResult2.value, node1);
|
||||
|
||||
const iterationResult3 = iterator.next();
|
||||
t.ok(iterationResult3.done);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test(
|
||||
"iterates backwards when adding nodes after creating iterator",
|
||||
function(t) {
|
||||
const dll = new DLL();
|
||||
|
||||
const node1 = DLL.createNode({ id: 1 });
|
||||
const node2 = DLL.createNode({ id: 2 });
|
||||
|
||||
const iterator = new Iterator(dll, true);
|
||||
|
||||
dll.insertBeginning(node1);
|
||||
dll.insertBeginning(node2);
|
||||
|
||||
const iterationResult1 = iterator.next();
|
||||
t.notOk(iterationResult1.done);
|
||||
t.same(iterationResult1.value, node1);
|
||||
|
||||
const iterationResult2 = iterator.next();
|
||||
t.notOk(iterationResult2.done);
|
||||
t.same(iterationResult2.value, node2);
|
||||
|
||||
const iterationResult3 = iterator.next();
|
||||
t.ok(iterationResult3.done);
|
||||
|
||||
t.end();
|
||||
}
|
||||
);
|
||||
|
||||
tap.test("stops iterating when node is detached", function(t) {
|
||||
const dll = new DLL();
|
||||
const iterator = new Iterator(dll);
|
||||
|
||||
const node1 = DLL.createNode({ id: 1 });
|
||||
const node2 = DLL.createNode({ id: 2 });
|
||||
|
||||
dll.insertBeginning(node1);
|
||||
dll.insertBeginning(node2);
|
||||
|
||||
const iterationResult1 = iterator.next();
|
||||
t.notOk(iterationResult1.done);
|
||||
t.same(iterationResult1.value, node2);
|
||||
|
||||
dll.remove(node1);
|
||||
|
||||
const iterationResult3 = iterator.next();
|
||||
t.ok(iterationResult3.done);
|
||||
|
||||
t.end();
|
||||
});
|
||||
28
node_modules/generic-pool/test/doubly-linked-list-test.js
generated
vendored
Normal file
28
node_modules/generic-pool/test/doubly-linked-list-test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
var tap = require("tap");
|
||||
var DLL = require("../lib/DoublyLinkedList");
|
||||
|
||||
tap.test("operations", function(t) {
|
||||
var dll = new DLL();
|
||||
|
||||
var item1 = { id: 1 };
|
||||
var item2 = { id: 2 };
|
||||
var item3 = { id: 3 };
|
||||
var item4 = { id: 4 };
|
||||
|
||||
dll.insertBeginning(DLL.createNode(item1));
|
||||
t.equal(dll.head.data, item1);
|
||||
|
||||
dll.insertEnd(DLL.createNode(item2));
|
||||
t.equal(dll.tail.data, item2);
|
||||
|
||||
dll.insertAfter(dll.tail, DLL.createNode(item3));
|
||||
t.equal(dll.tail.data, item3);
|
||||
|
||||
dll.insertBefore(dll.tail, DLL.createNode(item4));
|
||||
t.equal(dll.tail.data, item3);
|
||||
|
||||
dll.remove(dll.tail);
|
||||
t.equal(dll.tail.data, item4);
|
||||
|
||||
t.end();
|
||||
});
|
||||
77
node_modules/generic-pool/test/generic-pool-acquiretimeout-test.js
generated
vendored
Normal file
77
node_modules/generic-pool/test/generic-pool-acquiretimeout-test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
"use strict";
|
||||
|
||||
const tap = require("tap");
|
||||
const createPool = require("../").createPool;
|
||||
|
||||
tap.test("acquireTimeout handles timed out acquire calls", function(t) {
|
||||
const factory = {
|
||||
create: function() {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(function() {
|
||||
resolve({});
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
destroy: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
const config = {
|
||||
acquireTimeoutMillis: 20,
|
||||
idleTimeoutMillis: 150,
|
||||
log: false
|
||||
};
|
||||
|
||||
const pool = createPool(factory, config);
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(resource) {
|
||||
t.fail("wooops");
|
||||
})
|
||||
.catch(function(err) {
|
||||
t.match(err, /ResourceRequest timed out/);
|
||||
return pool.drain();
|
||||
})
|
||||
.then(function() {
|
||||
return pool.clear();
|
||||
})
|
||||
.then(function() {})
|
||||
.then(t.end)
|
||||
.catch(t.error);
|
||||
});
|
||||
|
||||
tap.test("acquireTimeout handles non timed out acquire calls", function(t) {
|
||||
const myResource = {};
|
||||
const factory = {
|
||||
create: function() {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(function() {
|
||||
resolve(myResource);
|
||||
}, 10);
|
||||
});
|
||||
},
|
||||
destroy: function() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
const config = {
|
||||
acquireTimeoutMillis: 400
|
||||
};
|
||||
|
||||
const pool = createPool(factory, config);
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(resource) {
|
||||
t.equal(resource, myResource);
|
||||
pool.release(resource);
|
||||
return pool.drain();
|
||||
})
|
||||
.then(function() {
|
||||
return pool.clear();
|
||||
})
|
||||
.then(t.end)
|
||||
.catch(t.error);
|
||||
});
|
||||
750
node_modules/generic-pool/test/generic-pool-test.js
generated
vendored
Normal file
750
node_modules/generic-pool/test/generic-pool-test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,750 @@
|
|||
"use strict";
|
||||
|
||||
const tap = require("tap");
|
||||
const createPool = require("../").createPool;
|
||||
const utils = require("./utils");
|
||||
const ResourceFactory = utils.ResourceFactory;
|
||||
|
||||
// tap.test('Pool expands only to max limit', function (t) {
|
||||
// const resourceFactory = new ResourceFactory()
|
||||
|
||||
// const config = {
|
||||
// max: 1
|
||||
// }
|
||||
|
||||
// const pool = createPool(resourceFactory, config)
|
||||
|
||||
// // NOTES:
|
||||
// // - request a resource
|
||||
// // - once we have it, request another and check the pool is fool
|
||||
// pool.acquire(function (err, obj) {
|
||||
// t.error(err)
|
||||
// const poolIsFull = !pool.acquire(function (err, obj) {
|
||||
// t.error(err)
|
||||
// t.equal(1, resourceFactory.created)
|
||||
// pool.release(obj)
|
||||
// utils.stopPool(pool)
|
||||
// t.end()
|
||||
// })
|
||||
// t.ok(poolIsFull)
|
||||
// t.equal(1, resourceFactory.created)
|
||||
// pool.release(obj)
|
||||
// })
|
||||
// })
|
||||
|
||||
// tap.test('Pool respects min limit', function (t) {
|
||||
// const resourceFactory = new ResourceFactory()
|
||||
|
||||
// const config
|
||||
// min: 1,
|
||||
// max: 2
|
||||
// }
|
||||
|
||||
// const pool = createPool(resourceFactory, config)
|
||||
|
||||
// // FIXME: this logic only works because we know it takes ~1ms to create a resource
|
||||
// // we need better hooks into the pool probably to observe this...
|
||||
// setTimeout(function () {
|
||||
// t.equal(resourceFactory.created, 1)
|
||||
// utils.stopPool(pool)
|
||||
// t.end()
|
||||
// }, 10)
|
||||
// })
|
||||
|
||||
tap.test("min and max limit defaults", function(t) {
|
||||
const resourceFactory = new ResourceFactory();
|
||||
|
||||
const pool = createPool(resourceFactory);
|
||||
|
||||
t.equal(1, pool.max);
|
||||
t.equal(0, pool.min);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("malformed min and max limits are ignored", function(t) {
|
||||
const resourceFactory = new ResourceFactory();
|
||||
|
||||
const config = {
|
||||
min: "asf",
|
||||
max: []
|
||||
};
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
t.equal(1, pool.max);
|
||||
t.equal(0, pool.min);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("min greater than max sets to max", function(t) {
|
||||
const resourceFactory = new ResourceFactory();
|
||||
|
||||
const config = {
|
||||
min: 5,
|
||||
max: 3
|
||||
};
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
t.equal(3, pool.max);
|
||||
t.equal(3, pool.min);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("supports priority on borrow", function(t) {
|
||||
// NOTE: this test is pretty opaque about what it's really testing/expecting...
|
||||
let borrowTimeLow = 0;
|
||||
let borrowTimeHigh = 0;
|
||||
let borrowCount = 0;
|
||||
|
||||
const resourceFactory = new ResourceFactory();
|
||||
|
||||
const config = {
|
||||
max: 1,
|
||||
priorityRange: 2
|
||||
};
|
||||
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
function lowPriorityOnFulfilled(obj) {
|
||||
const time = Date.now();
|
||||
if (time > borrowTimeLow) {
|
||||
borrowTimeLow = time;
|
||||
}
|
||||
borrowCount++;
|
||||
pool.release(obj);
|
||||
}
|
||||
|
||||
function highPriorityOnFulfilled(obj) {
|
||||
const time = Date.now();
|
||||
if (time > borrowTimeHigh) {
|
||||
borrowTimeHigh = time;
|
||||
}
|
||||
borrowCount++;
|
||||
pool.release(obj);
|
||||
}
|
||||
|
||||
const operations = [];
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const op = pool.acquire(1).then(lowPriorityOnFulfilled);
|
||||
operations.push(op);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const op = pool.acquire(0).then(highPriorityOnFulfilled);
|
||||
operations.push(op);
|
||||
}
|
||||
|
||||
Promise.all(operations)
|
||||
.then(function() {
|
||||
t.equal(20, borrowCount);
|
||||
t.equal(true, borrowTimeLow >= borrowTimeHigh);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
// FIXME: bad test!
|
||||
// pool.destroy makes no obligations to user about when it will destroy the resource
|
||||
// we should test that "destroyed" objects are not acquired again instead
|
||||
// tap.test('removes correct object on reap', function (t) {
|
||||
// const resourceFactory = new ResourceFactory()
|
||||
|
||||
// const config
|
||||
// max: 2
|
||||
// }
|
||||
|
||||
// const pool = createPool(resourceFactory, config)
|
||||
|
||||
// const op1 = pool.acquire()
|
||||
// .then(function (client) {
|
||||
// return new Promise(function (resolve, reject) {
|
||||
// // should be removed second
|
||||
// setTimeout(function () {
|
||||
// pool.destroy(client)
|
||||
// resolve()
|
||||
// }, 5)
|
||||
// })
|
||||
// })
|
||||
|
||||
// const op2 = pool.acquire()
|
||||
// .then(function (client) {
|
||||
// pool.destroy(client)
|
||||
// })
|
||||
|
||||
// Promise.all([op1, op2]).then(function () {
|
||||
// t.equal(1, resourceFactory.bin[0].id)
|
||||
// t.equal(0, resourceFactory.bin[1].id)
|
||||
// utils.stopPool(pool)
|
||||
// t.end()
|
||||
// })
|
||||
// .catch(t.threw)
|
||||
// })
|
||||
|
||||
tap.test("evictor removes instances on idletimeout", function(t) {
|
||||
const resourceFactory = new ResourceFactory();
|
||||
const config = {
|
||||
min: 2,
|
||||
max: 2,
|
||||
idleTimeoutMillis: 50,
|
||||
evictionRunIntervalMillis: 10
|
||||
};
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
setTimeout(function() {
|
||||
pool
|
||||
.acquire()
|
||||
.then(res => {
|
||||
t.ok(res.id > 1);
|
||||
return pool.release(res);
|
||||
})
|
||||
.then(() => {
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
});
|
||||
}, 120);
|
||||
});
|
||||
|
||||
tap.test("tests drain", function(t) {
|
||||
const count = 5;
|
||||
let acquired = 0;
|
||||
|
||||
const resourceFactory = new ResourceFactory();
|
||||
const config = {
|
||||
max: 2,
|
||||
idletimeoutMillis: 300000
|
||||
};
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
const operations = [];
|
||||
|
||||
function onAcquire(client) {
|
||||
acquired += 1;
|
||||
t.equal(typeof client.id, "number");
|
||||
setTimeout(function() {
|
||||
pool.release(client);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
// request 5 resources that release after 250ms
|
||||
for (let i = 0; i < count; i++) {
|
||||
const op = pool.acquire().then(onAcquire);
|
||||
operations.push(op);
|
||||
}
|
||||
// FIXME: what does this assertion prove?
|
||||
t.notEqual(count, acquired);
|
||||
|
||||
Promise.all(operations)
|
||||
.then(function() {
|
||||
return pool.drain();
|
||||
})
|
||||
.then(function() {
|
||||
t.equal(count, acquired);
|
||||
// short circuit the absurdly long timeouts above.
|
||||
pool.clear();
|
||||
})
|
||||
.then(function() {
|
||||
// subsequent calls to acquire should resolve an error.
|
||||
return pool.acquire().then(t.fail, function(e) {
|
||||
t.type(e, Error);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tap.test("handle creation errors", function(t) {
|
||||
let created = 0;
|
||||
const resourceFactory = {
|
||||
create: function() {
|
||||
created++;
|
||||
if (created < 5) {
|
||||
return Promise.reject(new Error("Error occurred."));
|
||||
} else {
|
||||
return Promise.resolve({ id: created });
|
||||
}
|
||||
},
|
||||
destroy: function(client) {}
|
||||
};
|
||||
const config = {
|
||||
max: 1
|
||||
};
|
||||
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
// FIXME: this section no longer proves anything as factory
|
||||
// errors no longer bubble up through the acquire call
|
||||
// we need to make the Pool an Emitter
|
||||
|
||||
// ensure that creation errors do not populate the pool.
|
||||
// for (const i = 0; i < 5; i++) {
|
||||
// pool.acquire(function (err, client) {
|
||||
// t.ok(err instanceof Error)
|
||||
// t.ok(client === null)
|
||||
// })
|
||||
// }
|
||||
|
||||
let called = false;
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(client) {
|
||||
t.equal(typeof client.id, "number");
|
||||
called = true;
|
||||
pool.release(client);
|
||||
})
|
||||
.then(function() {
|
||||
t.ok(called);
|
||||
t.equal(pool.pending, 0);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("handle creation errors for delayed creates", function(t) {
|
||||
let attempts = 0;
|
||||
|
||||
const resourceFactory = {
|
||||
create: function() {
|
||||
attempts++;
|
||||
if (attempts <= 5) {
|
||||
return Promise.reject(new Error("Error occurred."));
|
||||
} else {
|
||||
return Promise.resolve({ id: attempts });
|
||||
}
|
||||
},
|
||||
destroy: function(client) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
const config = {
|
||||
max: 1
|
||||
};
|
||||
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
let errorCount = 0;
|
||||
pool.on("factoryCreateError", function(err) {
|
||||
t.ok(err instanceof Error);
|
||||
errorCount++;
|
||||
});
|
||||
|
||||
let called = false;
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(client) {
|
||||
t.equal(typeof client.id, "number");
|
||||
called = true;
|
||||
pool.release(client);
|
||||
})
|
||||
.then(function() {
|
||||
t.ok(called);
|
||||
t.equal(errorCount, 5);
|
||||
t.equal(pool.pending, 0);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("getPoolSize", function(t) {
|
||||
let assertionCount = 0;
|
||||
const resourceFactory = new ResourceFactory();
|
||||
const config = {
|
||||
max: 2
|
||||
};
|
||||
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
const borrowedResources = [];
|
||||
|
||||
t.equal(pool.size, 0);
|
||||
assertionCount += 1;
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
borrowedResources.push(obj);
|
||||
t.equal(pool.size, 1);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
return pool.acquire();
|
||||
})
|
||||
.then(function(obj) {
|
||||
borrowedResources.push(obj);
|
||||
t.equal(pool.size, 2);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
pool.release(borrowedResources.shift());
|
||||
pool.release(borrowedResources.shift());
|
||||
})
|
||||
.then(function() {
|
||||
return pool.acquire();
|
||||
})
|
||||
.then(function(obj) {
|
||||
// should still be 2
|
||||
t.equal(pool.size, 2);
|
||||
assertionCount += 1;
|
||||
pool.release(obj);
|
||||
})
|
||||
.then(function() {
|
||||
t.equal(assertionCount, 4);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("availableObjectsCount", function(t) {
|
||||
let assertionCount = 0;
|
||||
const resourceFactory = new ResourceFactory();
|
||||
const config = {
|
||||
max: 2
|
||||
};
|
||||
|
||||
const pool = createPool(resourceFactory, config);
|
||||
|
||||
const borrowedResources = [];
|
||||
|
||||
t.equal(pool.available, 0);
|
||||
assertionCount += 1;
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
borrowedResources.push(obj);
|
||||
t.equal(pool.available, 0);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
return pool.acquire();
|
||||
})
|
||||
.then(function(obj) {
|
||||
borrowedResources.push(obj);
|
||||
t.equal(pool.available, 0);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
pool.release(borrowedResources.shift());
|
||||
t.equal(pool.available, 1);
|
||||
assertionCount += 1;
|
||||
|
||||
pool.release(borrowedResources.shift());
|
||||
t.equal(pool.available, 2);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
return pool.acquire();
|
||||
})
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 1);
|
||||
assertionCount += 1;
|
||||
pool.release(obj);
|
||||
|
||||
t.equal(pool.available, 2);
|
||||
assertionCount += 1;
|
||||
})
|
||||
.then(function() {
|
||||
t.equal(assertionCount, 7);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
// FIXME: bad test!
|
||||
// pool.destroy makes no obligations to user about when it will destroy the resource
|
||||
// we should test that "destroyed" objects are not acquired again instead
|
||||
// tap.test('removes from available objects on destroy', function (t) {
|
||||
// let destroyCalled = false
|
||||
// const factory = {
|
||||
// create: function () { return Promise.resolve({}) },
|
||||
// destroy: function (client) { destroyCalled = true; return Promise.resolve() }
|
||||
// }
|
||||
|
||||
// const config
|
||||
// max: 2
|
||||
// }
|
||||
|
||||
// const pool = createPool(factory, config)
|
||||
|
||||
// pool.acquire().then(function (obj) {
|
||||
// pool.destroy(obj)
|
||||
// })
|
||||
// .then(function () {
|
||||
// t.equal(destroyCalled, true)
|
||||
// t.equal(pool.available, 0)
|
||||
// utils.stopPool(pool)
|
||||
// t.end()
|
||||
// })
|
||||
// .catch(t.threw)
|
||||
// })
|
||||
|
||||
// FIXME: bad test!
|
||||
// pool.destroy makes no obligations to user about when it will destroy the resource
|
||||
// we should test that "destroyed" objects are not acquired again instead
|
||||
// tap.test('removes from available objects on validation failure', function (t) {
|
||||
// const destroyCalled = false
|
||||
// const validateCalled = false
|
||||
// const count = 0
|
||||
// const factory = {
|
||||
// create: function () { return Promise.resolve({count: count++}) },
|
||||
// destroy: function (client) { destroyCalled = client.count },
|
||||
// validate: function (client) {
|
||||
// validateCalled = true
|
||||
// return Promise.resolve(client.count > 0)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const config
|
||||
// max: 2,
|
||||
// testOnBorrow: true
|
||||
// }
|
||||
|
||||
// const pool = createPool(factory, config)
|
||||
|
||||
// pool.acquire()
|
||||
// .then(function (obj) {
|
||||
// pool.release(obj)
|
||||
// t.equal(obj.count, 0)
|
||||
// })
|
||||
// .then(function () {
|
||||
// return pool.acquire()
|
||||
// })
|
||||
// .then(function (obj2) {
|
||||
// pool.release(obj2)
|
||||
// t.equal(obj2.count, 1)
|
||||
// })
|
||||
// .then(function () {
|
||||
// t.equal(validateCalled, true)
|
||||
// t.equal(destroyCalled, 0)
|
||||
// t.equal(pool.available, 1)
|
||||
// utils.stopPool(pool)
|
||||
// t.end()
|
||||
// })
|
||||
// .catch(t.threw)
|
||||
// })
|
||||
|
||||
tap.test(
|
||||
"do schedule again if error occured when creating new Objects async",
|
||||
function(t) {
|
||||
// NOTE: we're simulating the first few resource attempts failing
|
||||
let resourceCreationAttempts = 0;
|
||||
|
||||
const factory = {
|
||||
create: function() {
|
||||
resourceCreationAttempts++;
|
||||
if (resourceCreationAttempts < 2) {
|
||||
return Promise.reject(new Error("Create Error"));
|
||||
}
|
||||
return Promise.resolve({});
|
||||
},
|
||||
destroy: function(client) {}
|
||||
};
|
||||
|
||||
const config = {
|
||||
max: 1
|
||||
};
|
||||
|
||||
const pool = createPool(factory, config);
|
||||
// pool.acquire(function () {})
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
}
|
||||
);
|
||||
|
||||
tap.test("returns only valid object to the pool", function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
|
||||
// Invalid release
|
||||
pool
|
||||
.release({})
|
||||
.catch(function(err) {
|
||||
t.match(err.message, /Resource not currently part of this pool/);
|
||||
})
|
||||
.then(function() {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
|
||||
// Valid release
|
||||
pool.release(obj).catch(t.error);
|
||||
t.equal(pool.available, 1);
|
||||
t.equal(pool.borrowed, 0);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
});
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("validate acquires object from the pool", function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("release to pool should work", function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
t.equal(pool.pending, 1);
|
||||
pool.release(obj);
|
||||
})
|
||||
.catch(t.threw);
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
t.equal(pool.pending, 0);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test(
|
||||
"isBorrowedResource should return true for borrowed resource",
|
||||
function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.isBorrowedResource(obj), true);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
}
|
||||
);
|
||||
|
||||
tap.test(
|
||||
"isBorrowedResource should return false for released resource",
|
||||
function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
pool.release(obj);
|
||||
return obj;
|
||||
})
|
||||
.then(function(obj) {
|
||||
t.equal(pool.isBorrowedResource(obj), false);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
}
|
||||
);
|
||||
|
||||
tap.test("destroy should redispense", function(t) {
|
||||
const pool = createPool(new ResourceFactory(), { max: 1 });
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
t.equal(pool.pending, 1);
|
||||
pool.destroy(obj);
|
||||
})
|
||||
.catch(t.threw);
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.equal(pool.available, 0);
|
||||
t.equal(pool.borrowed, 1);
|
||||
t.equal(pool.pending, 0);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("evictor start with acquire when autostart is false", function(t) {
|
||||
const pool = createPool(new ResourceFactory(), {
|
||||
evictionRunIntervalMillis: 10000,
|
||||
autostart: false
|
||||
});
|
||||
|
||||
t.equal(pool._scheduledEviction, null);
|
||||
|
||||
pool
|
||||
.acquire()
|
||||
.then(function(obj) {
|
||||
t.notEqual(pool._scheduledEviction, null);
|
||||
pool.release(obj);
|
||||
utils.stopPool(pool);
|
||||
t.end();
|
||||
})
|
||||
.catch(t.threw);
|
||||
});
|
||||
|
||||
tap.test("use method", function(t) {
|
||||
const pool = createPool(new ResourceFactory());
|
||||
const result = pool.use(function(resource) {
|
||||
t.equal(0, resource.id);
|
||||
return Promise.resolve();
|
||||
});
|
||||
result.then(function() {
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
tap.test("use method should resolve after fn promise is resolved", function(t) {
|
||||
const pool = createPool(new ResourceFactory());
|
||||
let done_with_resource = false;
|
||||
const result = pool.use(function(resource) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
setImmediate(function() {
|
||||
done_with_resource = true;
|
||||
resolve("value");
|
||||
});
|
||||
});
|
||||
});
|
||||
result.then(val => {
|
||||
t.equal(done_with_resource, true);
|
||||
t.equal(val, "value");
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
60
node_modules/generic-pool/test/resource-request-test.js
generated
vendored
Normal file
60
node_modules/generic-pool/test/resource-request-test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
var tap = require("tap");
|
||||
var ResourceRequest = require("../lib/ResourceRequest");
|
||||
|
||||
tap.test("can be created", function(t) {
|
||||
var create = function() {
|
||||
var request = new ResourceRequest(undefined, Promise); // eslint-disable-line no-unused-vars
|
||||
};
|
||||
t.doesNotThrow(create);
|
||||
t.end();
|
||||
});
|
||||
|
||||
tap.test("times out when created with a ttl", function(t) {
|
||||
var reject = function(err) {
|
||||
t.match(err, /ResourceRequest timed out/);
|
||||
t.end();
|
||||
};
|
||||
var resolve = function(r) {
|
||||
t.fail("should not resolve");
|
||||
};
|
||||
var request = new ResourceRequest(10, Promise); // eslint-disable-line no-unused-vars
|
||||
|
||||
request.promise.then(resolve, reject);
|
||||
});
|
||||
|
||||
tap.test("calls resolve when resolved", function(t) {
|
||||
var resource = {};
|
||||
var resolve = function(r) {
|
||||
t.equal(r, resource);
|
||||
t.end();
|
||||
};
|
||||
var reject = function(err) {
|
||||
t.error(err);
|
||||
};
|
||||
var request = new ResourceRequest(undefined, Promise);
|
||||
request.promise.then(resolve, reject);
|
||||
request.resolve(resource);
|
||||
});
|
||||
|
||||
tap.test("removeTimeout removes the timeout", function(t) {
|
||||
var reject = function(err) {
|
||||
t.error(err);
|
||||
};
|
||||
var request = new ResourceRequest(10, Promise);
|
||||
request.promise.then(undefined, reject);
|
||||
request.removeTimeout();
|
||||
setTimeout(function() {
|
||||
t.end();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
tap.test("does nothing if resolved more than once", function(t) {
|
||||
var request = new ResourceRequest(undefined, Promise);
|
||||
t.doesNotThrow(function() {
|
||||
request.resolve({});
|
||||
});
|
||||
t.doesNotThrow(function() {
|
||||
request.resolve({});
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
42
node_modules/generic-pool/test/utils.js
generated
vendored
Normal file
42
node_modules/generic-pool/test/utils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"use strict";
|
||||
|
||||
const Pool = require("../lib/Pool");
|
||||
|
||||
/**
|
||||
* Generic class for handling creation of resources
|
||||
* for testing
|
||||
*/
|
||||
class ResourceFactory {
|
||||
constructor() {
|
||||
this.created = 0;
|
||||
this.destroyed = 0;
|
||||
this.bin = [];
|
||||
}
|
||||
|
||||
create() {
|
||||
return Promise.resolve({ id: this.created++ });
|
||||
}
|
||||
|
||||
validate() {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
destroy(resource) {
|
||||
this.destroyed++;
|
||||
this.bin.push(resource);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
exports.ResourceFactory = ResourceFactory;
|
||||
|
||||
/**
|
||||
* drains and terminates the pool
|
||||
*
|
||||
* @param {Pool} pool [description]
|
||||
* @return {Promise} [description]
|
||||
*/
|
||||
exports.stopPool = function(pool) {
|
||||
return pool.drain().then(function() {
|
||||
return pool.clear();
|
||||
});
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue