2016-03-14 01:38:42 +00:00
|
|
|
var util = require('util');
|
|
|
|
var uuid = require('uuid');
|
2019-11-01 19:57:54 +00:00
|
|
|
var Long = require('long');
|
2019-11-01 18:30:06 +00:00
|
|
|
var client = require('../../lib/dist');
|
2016-03-14 01:38:42 +00:00
|
|
|
var FileLogger = require('../../src/common/log/fileLogger');
|
|
|
|
var NoopLogger = require('../../src/common/log/noopLogger');
|
|
|
|
|
2019-11-02 22:40:02 +00:00
|
|
|
// Make sure we mess with protobufjs setup for bug #91
|
|
|
|
var protobufJS = require('protobufjs');
|
|
|
|
protobufJS.util.Long = undefined;
|
|
|
|
protobufJS.configure();
|
|
|
|
|
2016-03-14 01:38:42 +00:00
|
|
|
var settings = {
|
2020-09-16 15:23:46 +00:00
|
|
|
log: new NoopLogger(),
|
2022-10-22 13:05:18 +00:00
|
|
|
useSslConnection: true,
|
|
|
|
validateServer: false
|
2016-03-14 01:38:42 +00:00
|
|
|
};
|
|
|
|
if (process.env.TESTS_VERBOSE_LOGGING === '1') {
|
|
|
|
settings.verboseLogging = true;
|
|
|
|
settings.log = new FileLogger('test-verbose.log');
|
|
|
|
}
|
|
|
|
|
2020-09-16 15:23:46 +00:00
|
|
|
function setUpWithGossipSeeds(cb) {
|
|
|
|
var gossipSeeds = [
|
|
|
|
new client.GossipSeed({ host: process.env.EVENTSTORE_HOST_1 || '192.168.33.10', port: 2113 }),
|
|
|
|
new client.GossipSeed({ host: process.env.EVENTSTORE_HOST_2 || '192.168.33.11', port: 2113 }),
|
|
|
|
new client.GossipSeed({ host: process.env.EVENTSTORE_HOST_3 || '192.168.33.12', port: 2113 }),
|
|
|
|
];
|
|
|
|
this.log = settings.log;
|
|
|
|
this.testStreamName = 'test-' + uuid.v4();
|
|
|
|
var connected = false;
|
|
|
|
this.conn = client.createConnection(settings, gossipSeeds);
|
|
|
|
this.conn
|
|
|
|
.connect()
|
|
|
|
.then(function () {
|
|
|
|
//Doesn't mean anything, connection is just initiated
|
|
|
|
settings.log.debug('Connection to %j initialized.', gossipSeeds);
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
settings.log.error(err, 'Initializing connection to %j failed.', gossipSeeds);
|
|
|
|
cb(err);
|
|
|
|
});
|
|
|
|
this.conn.on('closed', function (reason) {
|
|
|
|
if (connected) return;
|
|
|
|
var error = new Error('Connection failed: ' + reason);
|
|
|
|
settings.log.error(error, 'Connection to %j failed.', gossipSeeds);
|
|
|
|
cb(error);
|
|
|
|
});
|
|
|
|
this.conn.on('connected', function (tcpEndPoint) {
|
|
|
|
if (connected) return;
|
|
|
|
settings.log.debug('Connected to %j.', tcpEndPoint);
|
|
|
|
connected = true;
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setUpWithDns(cb) {
|
|
|
|
var clusterDns = 'discover://eventstore.local:2113';
|
|
|
|
this.log = settings.log;
|
|
|
|
this.testStreamName = 'test-' + uuid.v4();
|
|
|
|
var connected = false;
|
|
|
|
this.conn = client.createConnection(settings, clusterDns);
|
|
|
|
this.conn
|
|
|
|
.connect()
|
|
|
|
.then(function () {
|
|
|
|
//Doesn't mean anything, connection is just initiated
|
|
|
|
settings.log.debug('Connection to %j initialized.', clusterDns);
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
settings.log.error(err, 'Initializing connection to %j failed.', clusterDns);
|
|
|
|
cb(err);
|
|
|
|
});
|
|
|
|
this.conn.on('closed', function (reason) {
|
|
|
|
if (connected) return;
|
|
|
|
var error = new Error('Connection failed: ' + reason);
|
|
|
|
settings.log.error(error, 'Connection to %j failed.', clusterDns);
|
|
|
|
cb(error);
|
|
|
|
});
|
|
|
|
this.conn.on('connected', function (tcpEndPoint) {
|
|
|
|
if (connected) return;
|
|
|
|
settings.log.debug('Connected to %j.', tcpEndPoint);
|
|
|
|
connected = true;
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}
|
2016-03-14 01:38:42 +00:00
|
|
|
|
2020-09-16 15:23:46 +00:00
|
|
|
function setUpWithTcpEndpoint(cb) {
|
|
|
|
var tcpEndPoint = { host: process.env.EVENTSTORE_HOST || 'localhost', port: 1113 };
|
2016-03-14 01:38:42 +00:00
|
|
|
this.log = settings.log;
|
|
|
|
this.testStreamName = 'test-' + uuid.v4();
|
|
|
|
var connected = false;
|
|
|
|
this.conn = client.EventStoreConnection.create(settings, tcpEndPoint);
|
2020-09-16 15:23:46 +00:00
|
|
|
this.conn
|
|
|
|
.connect()
|
|
|
|
.then(function () {
|
|
|
|
//Doesn't mean anything, connection is just initiated
|
|
|
|
settings.log.debug('Connection to %j initialized.', tcpEndPoint);
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
settings.log.error(err, 'Initializing connection to %j failed.', tcpEndPoint);
|
|
|
|
cb(err);
|
|
|
|
});
|
2016-03-14 01:38:42 +00:00
|
|
|
this.conn.on('closed', function (reason) {
|
|
|
|
if (connected) return;
|
2020-09-16 15:23:46 +00:00
|
|
|
var error = new Error('Connection failed: ' + reason);
|
|
|
|
settings.log.error(error, 'Connection to %j failed.', tcpEndPoint);
|
2016-03-14 01:38:42 +00:00
|
|
|
cb(error);
|
|
|
|
});
|
2016-10-20 11:40:46 +00:00
|
|
|
this.conn.on('connected', function (tcpEndPoint) {
|
|
|
|
if (connected) return;
|
2020-09-16 15:23:46 +00:00
|
|
|
settings.log.debug('Connected to %j.', tcpEndPoint);
|
2016-03-14 01:38:42 +00:00
|
|
|
connected = true;
|
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function tearDown(cb) {
|
|
|
|
this.conn.close();
|
2020-09-16 15:23:46 +00:00
|
|
|
this.conn.on('closed', function () {
|
2016-03-14 01:38:42 +00:00
|
|
|
cb();
|
|
|
|
});
|
|
|
|
this.conn = null;
|
|
|
|
}
|
|
|
|
|
2016-03-15 00:55:35 +00:00
|
|
|
function areEqual(name, actual, expected) {
|
2016-03-14 01:38:42 +00:00
|
|
|
if (typeof expected !== 'object' || expected === null)
|
2020-09-16 15:23:46 +00:00
|
|
|
this.strictEqual(actual, expected, util.format('Failed %s === %s, got %s.', name, expected, actual));
|
|
|
|
else this.deepEqual(actual, expected, util.format('Failed %s deepEqual %j, got %j.', name, expected, actual));
|
2016-03-15 00:55:35 +00:00
|
|
|
}
|
2016-03-14 01:38:42 +00:00
|
|
|
|
2016-03-15 00:55:35 +00:00
|
|
|
function fail(reason) {
|
2016-03-14 01:38:42 +00:00
|
|
|
this.ok(false, reason);
|
2016-03-15 00:55:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function eventEqualEventData(name, resolvedEvent, eventData) {
|
|
|
|
var ev = resolvedEvent.originalEvent;
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(ev !== null, util.format('Failed %s !== null.', name + '.originalEvent'));
|
2016-03-15 00:55:35 +00:00
|
|
|
if (ev === null) return;
|
2020-09-16 15:23:46 +00:00
|
|
|
this.areEqual(name + '.originalEvent.eventId', ev.eventId, eventData.eventId);
|
|
|
|
this.areEqual(name + '.originalEvent.eventType', ev.eventType, eventData.type);
|
|
|
|
this.ok(Buffer.compare(ev.data, eventData.data) === 0, name + '.originalEvent.data is not equal to original data.');
|
|
|
|
this.ok(
|
|
|
|
Buffer.compare(ev.metadata, eventData.metadata) === 0,
|
|
|
|
name + '.originalEvent.metadata is not equal to original metadata.'
|
|
|
|
);
|
2016-03-15 00:55:35 +00:00
|
|
|
}
|
2016-03-14 01:38:42 +00:00
|
|
|
|
2019-11-01 19:57:54 +00:00
|
|
|
function testRecordedEvent(name, event) {
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(Long.isLong(event.eventNumber), name + '.eventNumber is not a Long');
|
|
|
|
this.ok(event.created instanceof Date, name + '.created is not a Date');
|
|
|
|
this.ok(typeof event.createdEpoch === 'number', name + '.createdEpoch is not a number');
|
2019-11-01 19:57:54 +00:00
|
|
|
}
|
|
|
|
|
2017-03-11 22:31:24 +00:00
|
|
|
function testLiveEvent(name, event, evNumber) {
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(event.event, name + '.event not defined (or null)');
|
|
|
|
this.ok(event.originalEvent, name + '.originalEvent not defined (or null)');
|
|
|
|
this.ok(event.isResolved === false, name + '.isResolved should be true');
|
|
|
|
this.ok(event.originalPosition instanceof client.Position, name + '.originalPosition is not an instance of Position');
|
|
|
|
this.ok(event.originalStreamId, name + '.originalStreamId not defined (or null)');
|
|
|
|
this.ok(Long.isLong(event.originalEventNumber), name + '.originalEventNumber is not a Long');
|
2017-03-11 22:31:24 +00:00
|
|
|
if (typeof evNumber === 'number') {
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(
|
|
|
|
event.originalEventNumber.toNumber() === evNumber,
|
|
|
|
name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber
|
|
|
|
);
|
2017-03-11 22:31:24 +00:00
|
|
|
}
|
2019-11-01 19:57:54 +00:00
|
|
|
testRecordedEvent.call(this, name + '.event', event.event);
|
2017-03-11 22:31:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function testReadEvent(name, event, evNumber) {
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(event.event, name + '.event not defined (or null)');
|
|
|
|
this.ok(event.originalEvent, name + '.originalEvent not defined (or null)');
|
|
|
|
this.ok(event.isResolved === false, name + '.isResolved should be true');
|
|
|
|
this.ok(event.originalPosition === null, name + '.originalPosition is not null');
|
|
|
|
this.ok(event.originalStreamId, name + '.originalStreamId not defined (or null)');
|
|
|
|
this.ok(Long.isLong(event.originalEventNumber), name + '.originalEventNumber is not a Long');
|
2017-03-11 22:31:24 +00:00
|
|
|
if (typeof evNumber === 'number') {
|
2020-09-16 15:23:46 +00:00
|
|
|
this.ok(
|
|
|
|
event.originalEventNumber.toNumber() === evNumber,
|
|
|
|
name + '.originalEventNumber expected ' + evNumber + ' got ' + event.originalEventNumber
|
|
|
|
);
|
2017-03-11 22:31:24 +00:00
|
|
|
}
|
2019-11-01 19:57:54 +00:00
|
|
|
testRecordedEvent.call(this, name + '.event', event.event);
|
2017-03-11 22:31:24 +00:00
|
|
|
}
|
|
|
|
|
2016-03-14 01:38:42 +00:00
|
|
|
var _ = {
|
2020-09-16 15:23:46 +00:00
|
|
|
tearDown: tearDown,
|
2016-03-14 01:38:42 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 15:23:46 +00:00
|
|
|
switch (process.env.EVENTSTORE_CONNECTION_TYPE) {
|
|
|
|
case 'gossip':
|
|
|
|
_.setUp = setUpWithGossipSeeds;
|
|
|
|
break;
|
|
|
|
case 'dns':
|
|
|
|
_.setUp = setUpWithDns;
|
|
|
|
break;
|
|
|
|
case 'tcp':
|
|
|
|
default:
|
|
|
|
_.setUp = setUpWithTcpEndpoint;
|
|
|
|
}
|
|
|
|
|
2016-03-14 01:38:42 +00:00
|
|
|
function wrap(name, testFunc) {
|
|
|
|
var base = _[name];
|
|
|
|
if (base === undefined) {
|
2020-09-16 15:23:46 +00:00
|
|
|
return function (test) {
|
2016-03-14 01:38:42 +00:00
|
|
|
settings.log.debug('--- %s ---', name);
|
|
|
|
test.areEqual = areEqual.bind(test);
|
|
|
|
test.fail = fail.bind(test);
|
2016-03-15 00:55:35 +00:00
|
|
|
test.eventEqualEventData = eventEqualEventData.bind(test);
|
2017-03-11 22:31:24 +00:00
|
|
|
test.testLiveEvent = testLiveEvent.bind(test);
|
|
|
|
test.testReadEvent = testReadEvent.bind(test);
|
2016-03-14 01:38:42 +00:00
|
|
|
return testFunc.call(this, test);
|
2020-09-16 15:23:46 +00:00
|
|
|
};
|
2016-03-14 01:38:42 +00:00
|
|
|
}
|
2020-09-16 15:23:46 +00:00
|
|
|
return function (cb) {
|
2016-03-14 01:38:42 +00:00
|
|
|
var self = this;
|
2020-09-16 15:23:46 +00:00
|
|
|
base.call(this, function (err) {
|
2016-03-14 01:38:42 +00:00
|
|
|
if (err) return cb(err);
|
|
|
|
return testFunc.call(self, cb);
|
|
|
|
});
|
2020-09-16 15:23:46 +00:00
|
|
|
};
|
2016-03-14 01:38:42 +00:00
|
|
|
}
|
|
|
|
|
2020-09-16 15:23:46 +00:00
|
|
|
module.exports.init = function (testSuite, addSetUpTearDownIfNotPresent) {
|
2016-03-14 01:38:42 +00:00
|
|
|
var thisObj = {};
|
|
|
|
if (addSetUpTearDownIfNotPresent === undefined) addSetUpTearDownIfNotPresent = true;
|
2020-09-16 15:23:46 +00:00
|
|
|
for (var k in testSuite) {
|
2016-03-14 01:38:42 +00:00
|
|
|
if (testSuite.hasOwnProperty(k)) {
|
|
|
|
testSuite[k] = wrap(k, testSuite[k]).bind(thisObj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!addSetUpTearDownIfNotPresent) return;
|
2020-09-16 15:23:46 +00:00
|
|
|
if (!testSuite.hasOwnProperty('setUp')) {
|
|
|
|
switch (process.env.EVENTSTORE_CONNECTION_TYPE) {
|
|
|
|
case 'gossip':
|
|
|
|
testSuite['setUp'] = setUpWithGossipSeeds.bind(thisObj);
|
|
|
|
break;
|
|
|
|
case 'dns':
|
|
|
|
testSuite['setUp'] = setUpWithDns.bind(thisObj);
|
|
|
|
break;
|
|
|
|
case 'tcp':
|
|
|
|
default:
|
|
|
|
testSuite['setUp'] = setUpWithTcpEndpoint.bind(thisObj);
|
|
|
|
}
|
|
|
|
}
|
2016-03-14 01:38:42 +00:00
|
|
|
if (!testSuite.hasOwnProperty('tearDown')) testSuite['tearDown'] = tearDown.bind(thisObj);
|
|
|
|
};
|
2020-09-16 15:23:46 +00:00
|
|
|
module.exports.settings = function (settingsOverride) {
|
2016-03-14 01:38:42 +00:00
|
|
|
var obj = {};
|
2020-09-16 15:23:46 +00:00
|
|
|
for (var prop in settings) {
|
2016-03-14 01:38:42 +00:00
|
|
|
obj[prop] = settings[prop];
|
|
|
|
}
|
|
|
|
if (!settingsOverride) return obj;
|
2020-09-16 15:23:46 +00:00
|
|
|
for (var prop in settingsOverride) {
|
2016-03-14 01:38:42 +00:00
|
|
|
obj[prop] = settingsOverride[prop];
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
};
|