-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
Copy pathmongodb-handshake.test.ts
137 lines (114 loc) · 4.47 KB
/
mongodb-handshake.test.ts
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
133
134
135
136
137
import { expect } from 'chai';
import type Sinon from 'sinon';
import * as sinon from 'sinon';
import {
Connection,
LEGACY_HELLO_COMMAND,
MongoServerError,
MongoServerSelectionError,
OpMsgRequest,
OpQueryRequest,
ServerApiVersion
} from '../../mongodb';
describe('MongoDB Handshake', () => {
let client;
afterEach(() => client.close());
context('when hello is too large', () => {
before(() => {
sinon.stub(Connection.prototype, 'command').callsFake(function (ns, cmd, options, callback) {
// @ts-expect-error: sinon will place wrappedMethod there
const command = Connection.prototype.command.wrappedMethod.bind(this);
if (cmd.hello || cmd[LEGACY_HELLO_COMMAND]) {
return command(
ns,
{ ...cmd, client: { driver: { name: 'a'.repeat(1000) } } },
options,
callback
);
}
return command(ns, cmd, options, callback);
});
});
after(() => sinon.restore());
it('should fail with an error relating to size', async function () {
client = this.configuration.newClient({ serverSelectionTimeoutMS: 2000 });
const error = await client.connect().catch(error => error);
if (this.configuration.isLoadBalanced) {
expect(error).to.be.instanceOf(MongoServerError);
} else {
expect(error).to.be.instanceOf(MongoServerSelectionError);
}
expect(error).to.match(/client metadata document must be less/);
});
});
context('when compressors are provided on the mongo client', () => {
let spy: Sinon.SinonSpy;
before(() => {
spy = sinon.spy(Connection.prototype, 'command');
});
after(() => sinon.restore());
it('constructs a handshake with the specified compressors', async function () {
client = this.configuration.newClient({ compressors: ['snappy'] });
// The load-balanced mode doesn’t perform SDAM,
// so `connect` doesn’t do anything unless authentication is enabled.
// Force the driver to send a command to the server in the noauth mode.
await client.db('admin').command({ ping: 1 });
expect(spy.called).to.be.true;
const handshakeDoc = spy.getCall(0).args[1];
expect(handshakeDoc).to.have.property('compression').to.deep.equal(['snappy']);
});
});
context('when load-balanced', function () {
let opMsgRequestToBinSpy: Sinon.SinonSpy;
beforeEach(() => {
opMsgRequestToBinSpy = sinon.spy(OpMsgRequest.prototype, 'toBin');
});
afterEach(() => sinon.restore());
it('sends the hello command as OP_MSG', {
metadata: { requires: { topology: 'load-balanced' } },
test: async function () {
client = this.configuration.newClient({ loadBalanced: true });
await client.db('admin').command({ ping: 1 });
expect(opMsgRequestToBinSpy).to.have.been.called;
}
});
});
context('when serverApi version is present', function () {
let opMsgRequestToBinSpy: Sinon.SinonSpy;
beforeEach(() => {
opMsgRequestToBinSpy = sinon.spy(OpMsgRequest.prototype, 'toBin');
});
afterEach(() => sinon.restore());
it('sends the hello command as OP_MSG', {
metadata: { requires: { topology: '!load-balanced', mongodb: '>=5.0' } },
test: async function () {
client = this.configuration.newClient({}, { serverApi: { version: ServerApiVersion.v1 } });
await client.connect();
expect(opMsgRequestToBinSpy).to.have.been.called;
}
});
});
context('when not load-balanced and serverApi version is not present', function () {
let opQueryRequestToBinSpy: Sinon.SinonSpy;
let opMsgRequestToBinSpy: Sinon.SinonSpy;
beforeEach(() => {
opQueryRequestToBinSpy = sinon.spy(OpQueryRequest.prototype, 'toBin');
opMsgRequestToBinSpy = sinon.spy(OpMsgRequest.prototype, 'toBin');
});
afterEach(() => sinon.restore());
it('sends the hello command as OP_MSG', {
metadata: { requires: { topology: '!load-balanced', mongodb: '>=5.0' } },
test: async function () {
if (this.configuration.serverApi) {
this.skipReason = 'Test requires serverApi to NOT be enabled';
return this.skip();
}
client = this.configuration.newClient();
await client.db('admin').command({ ping: 1 });
expect(opQueryRequestToBinSpy).to.have.been.called;
expect(opMsgRequestToBinSpy).to.have.been.called;
opMsgRequestToBinSpy.calledAfter(opQueryRequestToBinSpy);
}
});
});
});