generic-pool-test.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. "use strict";
  2. const tap = require("tap");
  3. const createPool = require("../").createPool;
  4. const utils = require("./utils");
  5. const ResourceFactory = utils.ResourceFactory;
  6. // tap.test('Pool expands only to max limit', function (t) {
  7. // const resourceFactory = new ResourceFactory()
  8. // const config = {
  9. // max: 1
  10. // }
  11. // const pool = createPool(resourceFactory, config)
  12. // // NOTES:
  13. // // - request a resource
  14. // // - once we have it, request another and check the pool is fool
  15. // pool.acquire(function (err, obj) {
  16. // t.error(err)
  17. // const poolIsFull = !pool.acquire(function (err, obj) {
  18. // t.error(err)
  19. // t.equal(1, resourceFactory.created)
  20. // pool.release(obj)
  21. // utils.stopPool(pool)
  22. // t.end()
  23. // })
  24. // t.ok(poolIsFull)
  25. // t.equal(1, resourceFactory.created)
  26. // pool.release(obj)
  27. // })
  28. // })
  29. // tap.test('Pool respects min limit', function (t) {
  30. // const resourceFactory = new ResourceFactory()
  31. // const config
  32. // min: 1,
  33. // max: 2
  34. // }
  35. // const pool = createPool(resourceFactory, config)
  36. // // FIXME: this logic only works because we know it takes ~1ms to create a resource
  37. // // we need better hooks into the pool probably to observe this...
  38. // setTimeout(function () {
  39. // t.equal(resourceFactory.created, 1)
  40. // utils.stopPool(pool)
  41. // t.end()
  42. // }, 10)
  43. // })
  44. tap.test("min and max limit defaults", function(t) {
  45. const resourceFactory = new ResourceFactory();
  46. const pool = createPool(resourceFactory);
  47. t.equal(1, pool.max);
  48. t.equal(0, pool.min);
  49. utils.stopPool(pool);
  50. t.end();
  51. });
  52. tap.test("malformed min and max limits are ignored", function(t) {
  53. const resourceFactory = new ResourceFactory();
  54. const config = {
  55. min: "asf",
  56. max: []
  57. };
  58. const pool = createPool(resourceFactory, config);
  59. t.equal(1, pool.max);
  60. t.equal(0, pool.min);
  61. utils.stopPool(pool);
  62. t.end();
  63. });
  64. tap.test("min greater than max sets to max", function(t) {
  65. const resourceFactory = new ResourceFactory();
  66. const config = {
  67. min: 5,
  68. max: 3
  69. };
  70. const pool = createPool(resourceFactory, config);
  71. t.equal(3, pool.max);
  72. t.equal(3, pool.min);
  73. utils.stopPool(pool);
  74. t.end();
  75. });
  76. tap.test("supports priority on borrow", function(t) {
  77. // NOTE: this test is pretty opaque about what it's really testing/expecting...
  78. let borrowTimeLow = 0;
  79. let borrowTimeHigh = 0;
  80. let borrowCount = 0;
  81. const resourceFactory = new ResourceFactory();
  82. const config = {
  83. max: 1,
  84. priorityRange: 2
  85. };
  86. const pool = createPool(resourceFactory, config);
  87. function lowPriorityOnFulfilled(obj) {
  88. const time = Date.now();
  89. if (time > borrowTimeLow) {
  90. borrowTimeLow = time;
  91. }
  92. borrowCount++;
  93. pool.release(obj);
  94. }
  95. function highPriorityOnFulfilled(obj) {
  96. const time = Date.now();
  97. if (time > borrowTimeHigh) {
  98. borrowTimeHigh = time;
  99. }
  100. borrowCount++;
  101. pool.release(obj);
  102. }
  103. const operations = [];
  104. for (let i = 0; i < 10; i++) {
  105. const op = pool.acquire(1).then(lowPriorityOnFulfilled);
  106. operations.push(op);
  107. }
  108. for (let i = 0; i < 10; i++) {
  109. const op = pool.acquire(0).then(highPriorityOnFulfilled);
  110. operations.push(op);
  111. }
  112. Promise.all(operations)
  113. .then(function() {
  114. t.equal(20, borrowCount);
  115. t.equal(true, borrowTimeLow >= borrowTimeHigh);
  116. utils.stopPool(pool);
  117. t.end();
  118. })
  119. .catch(t.threw);
  120. });
  121. // FIXME: bad test!
  122. // pool.destroy makes no obligations to user about when it will destroy the resource
  123. // we should test that "destroyed" objects are not acquired again instead
  124. // tap.test('removes correct object on reap', function (t) {
  125. // const resourceFactory = new ResourceFactory()
  126. // const config
  127. // max: 2
  128. // }
  129. // const pool = createPool(resourceFactory, config)
  130. // const op1 = pool.acquire()
  131. // .then(function (client) {
  132. // return new Promise(function (resolve, reject) {
  133. // // should be removed second
  134. // setTimeout(function () {
  135. // pool.destroy(client)
  136. // resolve()
  137. // }, 5)
  138. // })
  139. // })
  140. // const op2 = pool.acquire()
  141. // .then(function (client) {
  142. // pool.destroy(client)
  143. // })
  144. // Promise.all([op1, op2]).then(function () {
  145. // t.equal(1, resourceFactory.bin[0].id)
  146. // t.equal(0, resourceFactory.bin[1].id)
  147. // utils.stopPool(pool)
  148. // t.end()
  149. // })
  150. // .catch(t.threw)
  151. // })
  152. tap.test("evictor removes instances on idletimeout", function(t) {
  153. const resourceFactory = new ResourceFactory();
  154. const config = {
  155. min: 2,
  156. max: 2,
  157. idleTimeoutMillis: 50,
  158. evictionRunIntervalMillis: 10
  159. };
  160. const pool = createPool(resourceFactory, config);
  161. setTimeout(function() {
  162. pool
  163. .acquire()
  164. .then(res => {
  165. t.ok(res.id > 1);
  166. return pool.release(res);
  167. })
  168. .then(() => {
  169. utils.stopPool(pool);
  170. t.end();
  171. });
  172. }, 120);
  173. });
  174. tap.test("tests drain", function(t) {
  175. const count = 5;
  176. let acquired = 0;
  177. const resourceFactory = new ResourceFactory();
  178. const config = {
  179. max: 2,
  180. idletimeoutMillis: 300000
  181. };
  182. const pool = createPool(resourceFactory, config);
  183. const operations = [];
  184. function onAcquire(client) {
  185. acquired += 1;
  186. t.equal(typeof client.id, "number");
  187. setTimeout(function() {
  188. pool.release(client);
  189. }, 250);
  190. }
  191. // request 5 resources that release after 250ms
  192. for (let i = 0; i < count; i++) {
  193. const op = pool.acquire().then(onAcquire);
  194. operations.push(op);
  195. }
  196. // FIXME: what does this assertion prove?
  197. t.notEqual(count, acquired);
  198. Promise.all(operations)
  199. .then(function() {
  200. return pool.drain();
  201. })
  202. .then(function() {
  203. t.equal(count, acquired);
  204. // short circuit the absurdly long timeouts above.
  205. pool.clear();
  206. })
  207. .then(function() {
  208. // subsequent calls to acquire should resolve an error.
  209. return pool.acquire().then(t.fail, function(e) {
  210. t.type(e, Error);
  211. });
  212. })
  213. .then(function() {
  214. t.end();
  215. });
  216. });
  217. tap.test("clear promise resolves with no value", function(t) {
  218. let resources = [];
  219. const factory = {
  220. create: function create() {
  221. return new Promise(function tryCreate(resolve, reject) {
  222. let resource = resources.shift();
  223. if (resource) {
  224. resolve(resource);
  225. } else {
  226. process.nextTick(tryCreate.bind(this, resolve, reject));
  227. }
  228. });
  229. },
  230. destroy: function() {
  231. return Promise.resolve();
  232. }
  233. };
  234. const pool = createPool(factory, { max: 3, min: 3 });
  235. Promise.all([pool.acquire(), pool.acquire(), pool.acquire()]).then(all => {
  236. all.forEach(resource => {
  237. process.nextTick(pool.release.bind(pool), resource);
  238. });
  239. });
  240. t.equal(pool.pending, 3, "all acquisitions pending");
  241. pool
  242. .drain()
  243. .then(() => pool.clear())
  244. .then(resolved => {
  245. t.equal(resolved, undefined, "clear promise resolves with no value");
  246. t.end();
  247. });
  248. process.nextTick(() => {
  249. resources.push("a");
  250. resources.push("b");
  251. resources.push("c");
  252. });
  253. });
  254. tap.test("handle creation errors", function(t) {
  255. let created = 0;
  256. const resourceFactory = {
  257. create: function() {
  258. created++;
  259. if (created < 5) {
  260. return Promise.reject(new Error("Error occurred."));
  261. } else {
  262. return Promise.resolve({ id: created });
  263. }
  264. },
  265. destroy: function(client) {}
  266. };
  267. const config = {
  268. max: 1
  269. };
  270. const pool = createPool(resourceFactory, config);
  271. // FIXME: this section no longer proves anything as factory
  272. // errors no longer bubble up through the acquire call
  273. // we need to make the Pool an Emitter
  274. // ensure that creation errors do not populate the pool.
  275. // for (const i = 0; i < 5; i++) {
  276. // pool.acquire(function (err, client) {
  277. // t.ok(err instanceof Error)
  278. // t.ok(client === null)
  279. // })
  280. // }
  281. let called = false;
  282. pool
  283. .acquire()
  284. .then(function(client) {
  285. t.equal(typeof client.id, "number");
  286. called = true;
  287. pool.release(client);
  288. })
  289. .then(function() {
  290. t.ok(called);
  291. t.equal(pool.pending, 0);
  292. utils.stopPool(pool);
  293. t.end();
  294. })
  295. .catch(t.threw);
  296. });
  297. tap.test("handle creation errors for delayed creates", function(t) {
  298. let attempts = 0;
  299. const resourceFactory = {
  300. create: function() {
  301. attempts++;
  302. if (attempts <= 5) {
  303. return Promise.reject(new Error("Error occurred."));
  304. } else {
  305. return Promise.resolve({ id: attempts });
  306. }
  307. },
  308. destroy: function(client) {
  309. return Promise.resolve();
  310. }
  311. };
  312. const config = {
  313. max: 1
  314. };
  315. const pool = createPool(resourceFactory, config);
  316. let errorCount = 0;
  317. pool.on("factoryCreateError", function(err) {
  318. t.ok(err instanceof Error);
  319. errorCount++;
  320. });
  321. let called = false;
  322. pool
  323. .acquire()
  324. .then(function(client) {
  325. t.equal(typeof client.id, "number");
  326. called = true;
  327. pool.release(client);
  328. })
  329. .then(function() {
  330. t.ok(called);
  331. t.equal(errorCount, 5);
  332. t.equal(pool.pending, 0);
  333. utils.stopPool(pool);
  334. t.end();
  335. })
  336. .catch(t.threw);
  337. });
  338. tap.test("getPoolSize", function(t) {
  339. let assertionCount = 0;
  340. const resourceFactory = new ResourceFactory();
  341. const config = {
  342. max: 2
  343. };
  344. const pool = createPool(resourceFactory, config);
  345. const borrowedResources = [];
  346. t.equal(pool.size, 0);
  347. assertionCount += 1;
  348. pool
  349. .acquire()
  350. .then(function(obj) {
  351. borrowedResources.push(obj);
  352. t.equal(pool.size, 1);
  353. assertionCount += 1;
  354. })
  355. .then(function() {
  356. return pool.acquire();
  357. })
  358. .then(function(obj) {
  359. borrowedResources.push(obj);
  360. t.equal(pool.size, 2);
  361. assertionCount += 1;
  362. })
  363. .then(function() {
  364. pool.release(borrowedResources.shift());
  365. pool.release(borrowedResources.shift());
  366. })
  367. .then(function() {
  368. return pool.acquire();
  369. })
  370. .then(function(obj) {
  371. // should still be 2
  372. t.equal(pool.size, 2);
  373. assertionCount += 1;
  374. pool.release(obj);
  375. })
  376. .then(function() {
  377. t.equal(assertionCount, 4);
  378. utils.stopPool(pool);
  379. t.end();
  380. })
  381. .catch(t.threw);
  382. });
  383. tap.test("availableObjectsCount", function(t) {
  384. let assertionCount = 0;
  385. const resourceFactory = new ResourceFactory();
  386. const config = {
  387. max: 2
  388. };
  389. const pool = createPool(resourceFactory, config);
  390. const borrowedResources = [];
  391. t.equal(pool.available, 0);
  392. assertionCount += 1;
  393. pool
  394. .acquire()
  395. .then(function(obj) {
  396. borrowedResources.push(obj);
  397. t.equal(pool.available, 0);
  398. assertionCount += 1;
  399. })
  400. .then(function() {
  401. return pool.acquire();
  402. })
  403. .then(function(obj) {
  404. borrowedResources.push(obj);
  405. t.equal(pool.available, 0);
  406. assertionCount += 1;
  407. })
  408. .then(function() {
  409. pool.release(borrowedResources.shift());
  410. t.equal(pool.available, 1);
  411. assertionCount += 1;
  412. pool.release(borrowedResources.shift());
  413. t.equal(pool.available, 2);
  414. assertionCount += 1;
  415. })
  416. .then(function() {
  417. return pool.acquire();
  418. })
  419. .then(function(obj) {
  420. t.equal(pool.available, 1);
  421. assertionCount += 1;
  422. pool.release(obj);
  423. t.equal(pool.available, 2);
  424. assertionCount += 1;
  425. })
  426. .then(function() {
  427. t.equal(assertionCount, 7);
  428. utils.stopPool(pool);
  429. t.end();
  430. })
  431. .catch(t.threw);
  432. });
  433. // FIXME: bad test!
  434. // pool.destroy makes no obligations to user about when it will destroy the resource
  435. // we should test that "destroyed" objects are not acquired again instead
  436. // tap.test('removes from available objects on destroy', function (t) {
  437. // let destroyCalled = false
  438. // const factory = {
  439. // create: function () { return Promise.resolve({}) },
  440. // destroy: function (client) { destroyCalled = true; return Promise.resolve() }
  441. // }
  442. // const config
  443. // max: 2
  444. // }
  445. // const pool = createPool(factory, config)
  446. // pool.acquire().then(function (obj) {
  447. // pool.destroy(obj)
  448. // })
  449. // .then(function () {
  450. // t.equal(destroyCalled, true)
  451. // t.equal(pool.available, 0)
  452. // utils.stopPool(pool)
  453. // t.end()
  454. // })
  455. // .catch(t.threw)
  456. // })
  457. // FIXME: bad test!
  458. // pool.destroy makes no obligations to user about when it will destroy the resource
  459. // we should test that "destroyed" objects are not acquired again instead
  460. // tap.test('removes from available objects on validation failure', function (t) {
  461. // const destroyCalled = false
  462. // const validateCalled = false
  463. // const count = 0
  464. // const factory = {
  465. // create: function () { return Promise.resolve({count: count++}) },
  466. // destroy: function (client) { destroyCalled = client.count },
  467. // validate: function (client) {
  468. // validateCalled = true
  469. // return Promise.resolve(client.count > 0)
  470. // }
  471. // }
  472. // const config
  473. // max: 2,
  474. // testOnBorrow: true
  475. // }
  476. // const pool = createPool(factory, config)
  477. // pool.acquire()
  478. // .then(function (obj) {
  479. // pool.release(obj)
  480. // t.equal(obj.count, 0)
  481. // })
  482. // .then(function () {
  483. // return pool.acquire()
  484. // })
  485. // .then(function (obj2) {
  486. // pool.release(obj2)
  487. // t.equal(obj2.count, 1)
  488. // })
  489. // .then(function () {
  490. // t.equal(validateCalled, true)
  491. // t.equal(destroyCalled, 0)
  492. // t.equal(pool.available, 1)
  493. // utils.stopPool(pool)
  494. // t.end()
  495. // })
  496. // .catch(t.threw)
  497. // })
  498. tap.test(
  499. "do schedule again if error occured when creating new Objects async",
  500. function(t) {
  501. // NOTE: we're simulating the first few resource attempts failing
  502. let resourceCreationAttempts = 0;
  503. const factory = {
  504. create: function() {
  505. resourceCreationAttempts++;
  506. if (resourceCreationAttempts < 2) {
  507. return Promise.reject(new Error("Create Error"));
  508. }
  509. return Promise.resolve({});
  510. },
  511. destroy: function(client) {}
  512. };
  513. const config = {
  514. max: 1
  515. };
  516. const pool = createPool(factory, config);
  517. // pool.acquire(function () {})
  518. pool
  519. .acquire()
  520. .then(function(obj) {
  521. t.equal(pool.available, 0);
  522. pool.release(obj);
  523. utils.stopPool(pool);
  524. t.end();
  525. })
  526. .catch(t.threw);
  527. }
  528. );
  529. tap.test("returns only valid object to the pool", function(t) {
  530. const pool = createPool(new ResourceFactory(), { max: 1 });
  531. pool
  532. .acquire()
  533. .then(function(obj) {
  534. t.equal(pool.available, 0);
  535. t.equal(pool.borrowed, 1);
  536. // Invalid release
  537. pool
  538. .release({})
  539. .catch(function(err) {
  540. t.match(err.message, /Resource not currently part of this pool/);
  541. })
  542. .then(function() {
  543. t.equal(pool.available, 0);
  544. t.equal(pool.borrowed, 1);
  545. // Valid release
  546. pool.release(obj).catch(t.error);
  547. t.equal(pool.available, 1);
  548. t.equal(pool.borrowed, 0);
  549. utils.stopPool(pool);
  550. t.end();
  551. });
  552. })
  553. .catch(t.threw);
  554. });
  555. tap.test("validate acquires object from the pool", function(t) {
  556. const pool = createPool(new ResourceFactory(), { max: 1 });
  557. pool
  558. .acquire()
  559. .then(function(obj) {
  560. t.equal(pool.available, 0);
  561. t.equal(pool.borrowed, 1);
  562. pool.release(obj);
  563. utils.stopPool(pool);
  564. t.end();
  565. })
  566. .catch(t.threw);
  567. });
  568. tap.test("release to pool should work", function(t) {
  569. const pool = createPool(new ResourceFactory(), { max: 1 });
  570. pool
  571. .acquire()
  572. .then(function(obj) {
  573. t.equal(pool.available, 0);
  574. t.equal(pool.borrowed, 1);
  575. t.equal(pool.pending, 1);
  576. pool.release(obj);
  577. })
  578. .catch(t.threw);
  579. pool
  580. .acquire()
  581. .then(function(obj) {
  582. t.equal(pool.available, 0);
  583. t.equal(pool.borrowed, 1);
  584. t.equal(pool.pending, 0);
  585. pool.release(obj);
  586. utils.stopPool(pool);
  587. t.end();
  588. })
  589. .catch(t.threw);
  590. });
  591. tap.test(
  592. "isBorrowedResource should return true for borrowed resource",
  593. function(t) {
  594. const pool = createPool(new ResourceFactory(), { max: 1 });
  595. pool
  596. .acquire()
  597. .then(function(obj) {
  598. t.equal(pool.isBorrowedResource(obj), true);
  599. pool.release(obj);
  600. utils.stopPool(pool);
  601. t.end();
  602. })
  603. .catch(t.threw);
  604. }
  605. );
  606. tap.test(
  607. "isBorrowedResource should return false for released resource",
  608. function(t) {
  609. const pool = createPool(new ResourceFactory(), { max: 1 });
  610. pool
  611. .acquire()
  612. .then(function(obj) {
  613. pool.release(obj);
  614. return obj;
  615. })
  616. .then(function(obj) {
  617. t.equal(pool.isBorrowedResource(obj), false);
  618. utils.stopPool(pool);
  619. t.end();
  620. })
  621. .catch(t.threw);
  622. }
  623. );
  624. tap.test("destroy should redispense", function(t) {
  625. const pool = createPool(new ResourceFactory(), { max: 1 });
  626. pool
  627. .acquire()
  628. .then(function(obj) {
  629. t.equal(pool.available, 0);
  630. t.equal(pool.borrowed, 1);
  631. t.equal(pool.pending, 1);
  632. pool.destroy(obj);
  633. })
  634. .catch(t.threw);
  635. pool
  636. .acquire()
  637. .then(function(obj) {
  638. t.equal(pool.available, 0);
  639. t.equal(pool.borrowed, 1);
  640. t.equal(pool.pending, 0);
  641. pool.release(obj);
  642. utils.stopPool(pool);
  643. t.end();
  644. })
  645. .catch(t.threw);
  646. });
  647. tap.test("evictor start with acquire when autostart is false", function(t) {
  648. const pool = createPool(new ResourceFactory(), {
  649. evictionRunIntervalMillis: 10000,
  650. autostart: false
  651. });
  652. t.equal(pool._scheduledEviction, null);
  653. pool
  654. .acquire()
  655. .then(function(obj) {
  656. t.notEqual(pool._scheduledEviction, null);
  657. pool.release(obj);
  658. utils.stopPool(pool);
  659. t.end();
  660. })
  661. .catch(t.threw);
  662. });
  663. tap.test("use method", function(t) {
  664. const pool = createPool(new ResourceFactory());
  665. const result = pool.use(function(resource) {
  666. t.equal(0, resource.id);
  667. return Promise.resolve();
  668. });
  669. result.then(function() {
  670. t.end();
  671. });
  672. });
  673. tap.test("use method should resolve after fn promise is resolved", function(t) {
  674. const pool = createPool(new ResourceFactory());
  675. let done_with_resource = false;
  676. const result = pool.use(function(resource) {
  677. return new Promise(function(resolve, reject) {
  678. setImmediate(function() {
  679. done_with_resource = true;
  680. resolve("value");
  681. });
  682. });
  683. });
  684. result.then(val => {
  685. t.equal(done_with_resource, true);
  686. t.equal(val, "value");
  687. t.end();
  688. });
  689. });
  690. tap.test("evictor should not run when softIdleTimeoutMillis is -1", function(
  691. t
  692. ) {
  693. const resourceFactory = new ResourceFactory();
  694. const pool = createPool(resourceFactory, {
  695. evictionRunIntervalMillis: 10
  696. });
  697. pool
  698. .acquire()
  699. .then(res => pool.release(res))
  700. .then(() => {
  701. return new Promise(res => setTimeout(res, 30));
  702. })
  703. .then(() => t.equal(resourceFactory.destroyed, 0))
  704. .then(() => {
  705. utils.stopPool(pool);
  706. t.end();
  707. });
  708. });
  709. tap.test("should respect when maxWaitingClients is set to 0 ", function(t) {
  710. let assertionCount = 0;
  711. const resourceFactory = new ResourceFactory();
  712. const config = {
  713. max: 2,
  714. maxWaitingClients: 0
  715. };
  716. const pool = createPool(resourceFactory, config);
  717. const borrowedResources = [];
  718. t.equal(pool.size, 0);
  719. assertionCount += 1;
  720. pool
  721. .acquire()
  722. .then(function(obj) {
  723. borrowedResources.push(obj);
  724. t.equal(pool.size, 1);
  725. assertionCount += 1;
  726. })
  727. .then(function() {
  728. return pool.acquire();
  729. })
  730. .then(function(obj) {
  731. borrowedResources.push(obj);
  732. t.equal(pool.size, 2);
  733. assertionCount += 1;
  734. })
  735. .then(function() {
  736. return pool.acquire();
  737. })
  738. .then(function(obj) {
  739. // should not go in here
  740. t.equal(1, 2);
  741. })
  742. .catch(error => {
  743. t.equal(error.message, "max waitingClients count exceeded");
  744. t.end();
  745. });
  746. });