UNPKG

rethinkdbdash

Version:

A Node.js driver for RethinkDB with promises and a connection pool

361 lines (323 loc) 13 kB
var config = require(__dirname+'/config.js'); var r = require(__dirname+'/../lib')({pool: false, silent: true}); var util = require(__dirname+'/util/common.js'); var assert = require('assert'); var Promise = require('bluebird'); var uuid = util.uuid; var It = util.It; var uuid = util.uuid; var dbName, tableName, result, pks; var options = { max: 10, buffer: 2, host: config.host, port: config.port, authKey: config.authKey, discovery: false, silent: true }; It('`createPool` should create a PoolMaster and `getPoolMaster` should return it', function* (done) { try { r = r.createPools(options); assert(r.getPoolMaster(config)); assert.equal(r.getPoolMaster().getPools().length, 1) done(); } catch(e) { done(e); } }); //TODO try to make this tests a little more deterministic It('`run` should work without a connection if a pool exists', function* (done) { try { result = yield r.expr(1).run() assert.equal(result, 1); done() } catch(e) { done(e); } }); It('The pool should keep a buffer', function* (done) { try { result = yield [r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run()] assert.deepEqual(result, [1,1,1,1,1]); assert(r.getPool(0).getLength() >= options.buffer+result.length); setTimeout( function() { assert(r.getPool(0).getAvailableLength() >= result.length) // The connections created for the buffer may not be available yet assert.equal(r.getPool(0).getLength(), r.getPool(0).getLength()) done(); }, 500) } catch(e) { done(e); } }); It('A noreply query should release the connection', function* (done) { try { var numConnections = r.getPool(0).getLength(); yield r.expr(1).run({noreply: true}) assert.equal(r.getPool(0).getLength(), numConnections); done(); } catch(e) { console.log(e) done(e); } }); It('The pool should not have more than `options.max` connections', function* (done) { try { result = yield [r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run()] assert.deepEqual(result, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) assert.equal(r.getPool(0).getLength(), options.max) setTimeout( function() { assert.equal(r.getPool(0).getAvailableLength(), options.max) assert.equal(r.getPool(0).getAvailableLength(), r.getPool(0).getLength()) done() }, 500) } catch(e) { done(e); } }); It('Init for `pool.js`', function* (done) { try { dbName = uuid(); tableName = uuid(); result = yield r.dbCreate(dbName).run(); assert.equal(result.dbs_created, 1); result = yield r.db(dbName).tableCreate(tableName).run(); assert.equal(result.tables_created, 1); result = yield r.db(dbName).table(tableName).insert(eval('['+new Array(10000).join('{}, ')+'{}]')).run(); assert.equal(result.inserted, 10000); pks = result.generated_keys; done(); } catch(e) { done(e); } }) It('Updating data to make it heavier', function* (done) { try { //Making bigger documents to retrieve multiple batches var result = yield r.db(dbName).table(tableName).update({ "foo": uuid(), "fooo": uuid(), "foooo": uuid(), "fooooo": uuid(), "foooooo": uuid(), "fooooooo": uuid(), "foooooooo": uuid(), "fooooooooo": uuid(), "foooooooooo": uuid(), date: r.now() }).run(); done(); } catch(e) { done(e); } }) It('The pool should release a connection only when the cursor has fetch everything or get closed', function* (done) { try { result = yield [r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true}),r.db(dbName).table(tableName).run({cursor: true})]; assert.equal(result.length, 10); assert.equal(r.getPool(0).getAvailableLength(), 0); yield result[0].toArray(); assert.equal(r.getPool(0).getAvailableLength(), 1); yield result[1].toArray(); assert.equal(r.getPool(0).getAvailableLength(), 2); yield result[2].close(); assert.equal(r.getPool(0).getAvailableLength(), 3); yield [result[3].close(), result[4].close(), result[5].close(), result[6].close(), result[7].close(), result[8].close(), result[9].close()] done(); } catch(e) { done(e); } }); It('The pool should shrink if a connection is not used for some time', function* (done) { try{ r.getPool(0).setOptions({timeoutGb: 100}); result = yield [r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run()] assert.deepEqual(result, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) setTimeout(function() { assert.equal(r.getPool(0).getAvailableLength(), options.buffer) assert.equal(r.getPool(0).getLength(), options.buffer) done() },400) } catch(e) { done(e); } }); It('`poolMaster.drain` should eventually remove all the connections', function* (done) { try{ yield r.getPoolMaster().drain(); assert.equal(r.getPool(0).getAvailableLength(), 0) assert.equal(r.getPool(0).getLength(), 0) done() } catch(e) { done(e); } }); It('If the pool cannot create a connection, it should reject queries', function* (done) { try { var r = require(__dirname+'/../lib')({host: "notarealhost", buffer: 1, max: 2, silent: true}); yield r.expr(1).run() done(new Error("Was expecting an error")); } catch(e) { if (e.message === "None of the pools have an opened connection and failed to open a new one.") { done() } else { done(e); } } }); It('If the pool cannot create a connection, it should reject queries - timeout', function* (done) { try { var r = require(__dirname+'/../lib')({host: "notarealhost", buffer: 1, max: 2, silent: true}); yield new Promise(function(resolve, reject) { setTimeout(resolve, 1000) }); yield r.expr(1).run() done(new Error("Was expecting an error")); } catch(e) { if (e.message === "None of the pools have an opened connection and failed to open a new one.") { done() } else { done(e); } } }); It('If the pool is drained, it should reject queries - 1', function* (done) { try { var r = require(__dirname+'/../lib')({buffer: 1, max: 2, silent: true}); r.getPoolMaster().drain(); var result = yield r.expr(1).run(); done(new Error("Was expecting an error")); } catch(e) { if (e.message === "None of the pools have an opened connection and failed to open a new one.") { done() } else { done(e); } } }); It('If the pool is drained, it should reject queries - 2', function* (done) { try { var r = require(__dirname+'/../lib')({buffer: 1, max: 2, silent: true}); yield r.getPoolMaster().drain(); var result = yield r.expr(1).run(); done(new Error("Was expecting an error")); } catch(e) { if (e.message === "None of the pools have an opened connection and failed to open a new one.") { done() } else { done(e); } } }); It('`drain` should work in case of failures', function* (done) { try { r = r.createPools({ port: 80, // non valid port silent: true, timeoutError: 100 }); var pool = r.getPool(0); // Sleep 1 sec yield new Promise(function(resolve, reject) { setTimeout(resolve, 150) }); pool.drain(); // timeoutReconnect should have been canceled assert.equal(pool.timeoutReconnect, null); pool.options.silent = false; yield new Promise(function(resolve, reject) { setTimeout(resolve, 1000) }); done(); } catch(e) { done(e); } }); /* // This doesn't work anymore because since the JSON protocol was introduced. It('The pool should remove a connection if it errored', function* (done) { try{ r.getPool(0).setOptions({timeoutGb: 60*60*1000}); result = yield [r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run(), r.expr(1).run()] assert.deepEqual(result, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) // This query will make the error return an error -1 result = yield r.expr(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1).add(1) .run() } catch(e) { if ((true) || (e.message === "Client is buggy (failed to deserialize protobuf)")) { // We expect the connection that errored to get closed in the next second setTimeout(function() { assert.equal(r.getPool().getAvailableLength(), options.max-1) assert.equal(r.getPool().getLength(), options.max-1) done() }, 1000) } else { done(e); } } }); */