Files
cgm-remote-monitor/tests/mongo-storage.retry.test.js
T

135 lines
3.8 KiB
JavaScript

'use strict';
var should = require('should');
var mongodb = require('mongodb');
describe('mongo storage retry lifecycle', function () {
var originalMongoClient = mongodb.MongoClient;
var originalSetTimeout = global.setTimeout;
function setMongoClient(fakeMongoClient) {
Object.defineProperty(mongodb, 'MongoClient', {
configurable: true,
enumerable: true,
value: fakeMongoClient,
writable: true
});
}
afterEach(function () {
setMongoClient(originalMongoClient);
global.setTimeout = originalSetTimeout;
delete require.cache[require.resolve('../lib/storage/mongo-storage')];
});
it('closes failed retry clients and calls back only after a successful retry', function (done) {
var createdClients = [];
var connectAttempts = 0;
var retryDelays = [];
function FakeMongoClient() {
this.closed = 0;
createdClients.push(this);
}
FakeMongoClient.prototype.on = function () {};
FakeMongoClient.prototype.connect = function () {
connectAttempts += 1;
if (connectAttempts === 1) {
var err = new Error('server selection failed');
err.name = 'MongoServerSelectionError';
return Promise.reject(err);
}
return Promise.resolve();
};
FakeMongoClient.prototype.db = function () {
return {
databaseName: 'testdb',
command: function () {
return Promise.resolve({ authInfo: { authenticatedUserRoles: [] } });
},
collection: function (name) {
return { collectionName: name };
}
};
};
FakeMongoClient.prototype.close = function () {
this.closed += 1;
return Promise.resolve();
};
setMongoClient(FakeMongoClient);
global.setTimeout = function (fn, ms) {
retryDelays.push(ms);
Promise.resolve().then(fn);
return 1;
};
delete require.cache[require.resolve('../lib/storage/mongo-storage')];
var store = require('../lib/storage/mongo-storage');
var callbackCount = 0;
store({ storageURI: 'mongodb://example/testdb' }, function (err, db) {
callbackCount += 1;
should.not.exist(err);
should.exist(db);
callbackCount.should.equal(1);
connectAttempts.should.equal(2);
createdClients.length.should.equal(2);
createdClients[0].closed.should.equal(1);
createdClients[1].closed.should.equal(0);
retryDelays.should.eql([3000]);
db.db.databaseName.should.equal('testdb');
done();
}, true);
});
it('closes the client and reports authentication failure once', function (done) {
var createdClients = [];
var retryDelays = [];
function FakeMongoClient() {
this.closed = 0;
createdClients.push(this);
}
FakeMongoClient.prototype.on = function () {};
FakeMongoClient.prototype.connect = function () {
return Promise.reject(new Error('AuthenticationFailed: bad auth'));
};
FakeMongoClient.prototype.close = function () {
this.closed += 1;
return Promise.resolve();
};
setMongoClient(FakeMongoClient);
global.setTimeout = function (fn, ms) {
retryDelays.push(ms);
Promise.resolve().then(fn);
return 1;
};
delete require.cache[require.resolve('../lib/storage/mongo-storage')];
var store = require('../lib/storage/mongo-storage');
var callbackCount = 0;
store({ storageURI: 'mongodb://example/testdb' }, function (err, db) {
callbackCount += 1;
should.exist(err);
should.not.exist(db);
err.message.should.equal('MongoDB authentication failed! Double check the URL has the right username and password in MONGODB_URI.');
callbackCount.should.equal(1);
createdClients.length.should.equal(1);
createdClients[0].closed.should.equal(1);
retryDelays.should.eql([]);
done();
}, true);
});
});