Skip to content

Commit 3926158

Browse files
committed
add unit test
1 parent 669c6d1 commit 3926158

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { expect } from 'chai';
2+
import { type TopologyDescription } from 'mongodb-legacy';
3+
import * as sinon from 'sinon';
4+
5+
import {
6+
type MongoClient,
7+
ObjectId,
8+
Server,
9+
ServerDescription,
10+
Topology,
11+
TOPOLOGY_DESCRIPTION_CHANGED,
12+
type TopologyDescriptionChangedEvent
13+
} from '../../mongodb';
14+
15+
const SDAM_EVENTS = [
16+
// Topology events
17+
TOPOLOGY_DESCRIPTION_CHANGED
18+
];
19+
20+
describe('Server Discovery and Monitoring', function () {
21+
let serverConnect: sinon.SinonStub;
22+
let topologySelectServer: sinon.SinonStub;
23+
let client: MongoClient;
24+
let events: TopologyDescriptionChangedEvent[] = [];
25+
26+
function getNewDescription() {
27+
const [topologyDescriptionChanged] = events.filter(
28+
x => x.name === 'topologyDescriptionChanged'
29+
);
30+
events = [];
31+
return topologyDescriptionChanged.newDescription;
32+
}
33+
34+
before(async function () {
35+
serverConnect = sinon.stub(Server.prototype, 'connect').callsFake(function () {
36+
this.s.state = 'connected';
37+
this.emit('connect');
38+
});
39+
topologySelectServer = sinon
40+
.stub(Topology.prototype, 'selectServer')
41+
.callsFake(async function (_selector, _options) {
42+
topologySelectServer.restore();
43+
44+
const fakeServer = { s: { state: 'connected' }, removeListener: () => true };
45+
return fakeServer;
46+
});
47+
const events = [];
48+
client.on('topologyDescriptionChanged', event => events.push(event));
49+
await client.connect();
50+
});
51+
52+
after(function () {
53+
serverConnect.restore();
54+
});
55+
56+
describe('when a newer primary is detected', function () {
57+
it('steps down original primary to unknown server description with appropriate error message', async function () {
58+
let newDescription: TopologyDescription;
59+
// Start with a as primary
60+
client.topology.serverUpdateHandler(
61+
new ServerDescription('a:27017', {
62+
ok: 1,
63+
helloOk: true,
64+
isWritablePrimary: true,
65+
hosts: ['a:27017', 'b:27017'],
66+
setName: 'rs',
67+
setVersion: 1,
68+
electionId: ObjectId.createFromHexString('000000000000000000000001'),
69+
minWireVersion: 0,
70+
maxWireVersion: 21
71+
})
72+
);
73+
74+
newDescription = getNewDescription();
75+
76+
expect(newDescription.type).to.equal('ReplicaSetWithPrimary');
77+
78+
// b is elected as primary, a gets marked stale
79+
client.topology.serverUpdateHandler(
80+
new ServerDescription('b:27017', {
81+
ok: 1,
82+
helloOk: true,
83+
isWritablePrimary: true,
84+
hosts: ['a:27017', 'b:27017'],
85+
setName: 'rs',
86+
setVersion: 2,
87+
electionId: ObjectId.createFromHexString('000000000000000000000001'),
88+
minWireVersion: 0,
89+
maxWireVersion: 21
90+
})
91+
);
92+
93+
newDescription = getNewDescription();
94+
95+
let aOutcome = newDescription.servers.get('a:27017');
96+
expect(aOutcome.error).to.match(/primary marked stale due to discovery of newer primary/);
97+
98+
// a still incorrectly reports as primary
99+
client.topology.serverUpdateHandler(
100+
new ServerDescription('a:27017', {
101+
ok: 1,
102+
helloOk: true,
103+
isWritablePrimary: true,
104+
hosts: ['a:27017', 'b:27017'],
105+
setName: 'rs',
106+
setVersion: 1,
107+
electionId: ObjectId.createFromHexString('000000000000000000000001'),
108+
minWireVersion: 0,
109+
maxWireVersion: 21
110+
})
111+
);
112+
113+
newDescription = getNewDescription();
114+
115+
aOutcome = newDescription.servers.get('a:27017');
116+
117+
expect(aOutcome.type).to.equal('Unknown');
118+
expect(aOutcome.error).to.match(
119+
/primary marked stale due to electionId\/setVersion mismatch: server setVersion: \d+, server electionId: \d{24}, topology setVersion: \d, topology electionId: \d{24}/
120+
);
121+
});
122+
});
123+
});

0 commit comments

Comments
 (0)