/
replset_state.test.js
132 lines (114 loc) · 3.45 KB
/
replset_state.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict';
const expect = require('chai').expect,
f = require('util').format,
p = require('path'),
fs = require('fs'),
ObjectId = require('bson').ObjectId,
ReplSetState = require('../../../lib/core/topologies/replset_state');
describe('ReplicaSet state', function() {
const path = p.resolve(__dirname, '../../spec/server-discovery-and-monitoring/rs');
fs.readdirSync(path)
.filter(x => x.indexOf('.json') !== -1)
.filter(x => !x.includes('repeated'))
.forEach(x => {
var testData = require(f('%s/%s', path, x));
it(testData.description, function(done) {
executeEntry(testData, done);
});
});
});
function executeEntry(testData, callback) {
var uri = testData.uri;
var phases = testData.phases;
// Get replicaset name if any
var match = uri.match(/replicaSet=[a-z|A-Z|0-9]*/);
var replicaSet = match ? match.toString().split(/=/)[1] : null;
// Replicaset
// Create a replset state
var state = new ReplSetState({ setName: replicaSet });
// Get all the server instances
var parts = uri
.split('mongodb://')[1]
.split('/')[0]
.split(',');
// For each of the servers
parts.forEach(function(x) {
var params = x.split(':');
state.update({
name: f('%s:%s', params[0], params[1] ? parseInt(params[1], 10) : 27017),
lastIsMaster: function() {
return null;
},
equals: function(s) {
if (typeof s === 'string') return s === this.name;
return s.name === this.name;
},
destroy: function() {}
});
});
// Run each phase
executePhases(phases, state, callback);
}
function executePhases(phases, state, callback) {
if (phases.length === 0) {
return callback(null, null);
}
executePhase(phases.shift(), state, err => {
if (err) return callback(err, null);
return executePhases(phases, state, callback);
});
}
function executePhase(phase, state, callback) {
var responses = phase.responses;
var outcome = phase.outcome;
// Apply all the responses
responses.forEach(function(x) {
if (Object.keys(x[1]).length === 0) {
state.remove({
name: x[0],
lastIsMaster: function() {
return null;
},
equals: function(s) {
if (typeof s === 'string') return s === this.name;
return s.name === this.name;
},
destroy: function() {}
});
} else {
var ismaster = x[1];
if (ismaster.electionId) ismaster.electionId = new ObjectId(ismaster.electionId.$oid);
state.update({
name: x[0],
lastIsMaster: function() {
return ismaster;
},
equals: function(s) {
if (typeof s === 'string') return s === this.name;
return s.name === this.name;
},
destroy: function() {}
});
}
});
// Validate the state of the final outcome
for (var name in outcome.servers) {
try {
if (outcome.servers[name].electionId) {
outcome.servers[name].electionId = new ObjectId(outcome.servers[name].electionId.$oid);
}
expect(state.set[name]).to.exist;
for (var n in outcome.servers[name]) {
if (outcome.servers[name][n]) {
expect(state.set[name][n]).to.eql(outcome.servers[name][n]);
}
}
} catch (e) {
return callback(e);
}
}
// // Check the topology type
expect(state.topologyType).to.equal(outcome.topologyType);
expect(state.setName).to.equal(outcome.setName);
callback(null, null);
}