|
1 | 1 | import { expect } from 'chai'; |
| 2 | +import * as fs from 'fs'; |
| 3 | +import * as net from 'net'; |
| 4 | +import * as path from 'path'; |
2 | 5 | import * as process from 'process'; |
| 6 | +import * as sinon from 'sinon'; |
| 7 | +import * as tls from 'tls'; |
3 | 8 |
|
4 | 9 | import { |
5 | 10 | CancellationToken, |
6 | 11 | type ClientMetadata, |
7 | 12 | connect, |
8 | 13 | type Connection, |
9 | 14 | type ConnectionOptions, |
| 15 | + DEFAULT_KEEP_ALIVE_INITIAL_DELAY_MS, |
10 | 16 | HostAddress, |
11 | 17 | isHello, |
12 | 18 | LEGACY_HELLO_COMMAND, |
13 | 19 | makeClientMetadata, |
| 20 | + makeSocket, |
14 | 21 | MongoClientAuthProviders, |
15 | 22 | MongoCredentials, |
16 | 23 | MongoNetworkError, |
@@ -448,4 +455,104 @@ describe('Connect Tests', function () { |
448 | 455 | }); |
449 | 456 | }); |
450 | 457 | }); |
| 458 | + |
| 459 | + describe('makeSocket', function () { |
| 460 | + let tlsServer: tls.Server; |
| 461 | + let tlsPort: number; |
| 462 | + let setKeepAliveSpy: sinon.SinonSpy; |
| 463 | + let setNoDelaySpy: sinon.SinonSpy; |
| 464 | + |
| 465 | + const serverPem = fs.readFileSync( |
| 466 | + path.join(__dirname, '../../integration/auth/ssl/server.pem') |
| 467 | + ); |
| 468 | + |
| 469 | + before(function (done) { |
| 470 | + // @SECLEVEL=0 allows the legacy test certificate (signed with SHA-1/1024-bit RSA) |
| 471 | + // to be accepted by OpenSSL 3.x, which rejects at the default security level. |
| 472 | + tlsServer = tls.createServer( |
| 473 | + { key: serverPem, cert: serverPem, ciphers: 'DEFAULT:@SECLEVEL=0' }, |
| 474 | + () => { |
| 475 | + /* empty */ |
| 476 | + } |
| 477 | + ); |
| 478 | + tlsServer.listen(0, '127.0.0.1', () => { |
| 479 | + tlsPort = (tlsServer.address() as net.AddressInfo).port; |
| 480 | + done(); |
| 481 | + }); |
| 482 | + }); |
| 483 | + |
| 484 | + after(function () { |
| 485 | + tlsServer?.close(); |
| 486 | + }); |
| 487 | + |
| 488 | + beforeEach(function () { |
| 489 | + setKeepAliveSpy = sinon.spy(net.Socket.prototype, 'setKeepAlive'); |
| 490 | + setNoDelaySpy = sinon.spy(net.Socket.prototype, 'setNoDelay'); |
| 491 | + }); |
| 492 | + |
| 493 | + afterEach(function () { |
| 494 | + sinon.restore(); |
| 495 | + }); |
| 496 | + |
| 497 | + context('when tls is enabled', function () { |
| 498 | + it('calls setKeepAlive with default keepAliveInitialDelay', async function () { |
| 499 | + const socket = await makeSocket({ |
| 500 | + hostAddress: new HostAddress(`127.0.0.1:${tlsPort}`), |
| 501 | + tls: true, |
| 502 | + rejectUnauthorized: false, |
| 503 | + ciphers: 'DEFAULT:@SECLEVEL=0' |
| 504 | + } as ConnectionOptions); |
| 505 | + socket.destroy(); |
| 506 | + |
| 507 | + expect(setKeepAliveSpy).to.have.been.calledWith(true, DEFAULT_KEEP_ALIVE_INITIAL_DELAY_MS); |
| 508 | + }); |
| 509 | + |
| 510 | + it('calls setKeepAlive with custom keepAliveInitialDelay', async function () { |
| 511 | + const socket = await makeSocket({ |
| 512 | + hostAddress: new HostAddress(`127.0.0.1:${tlsPort}`), |
| 513 | + tls: true, |
| 514 | + rejectUnauthorized: false, |
| 515 | + ciphers: 'DEFAULT:@SECLEVEL=0', |
| 516 | + keepAliveInitialDelay: 5000 |
| 517 | + } as ConnectionOptions); |
| 518 | + socket.destroy(); |
| 519 | + |
| 520 | + expect(setKeepAliveSpy).to.have.been.calledWith(true, 5000); |
| 521 | + }); |
| 522 | + |
| 523 | + it('calls setNoDelay with true by default', async function () { |
| 524 | + const socket = await makeSocket({ |
| 525 | + hostAddress: new HostAddress(`127.0.0.1:${tlsPort}`), |
| 526 | + tls: true, |
| 527 | + rejectUnauthorized: false, |
| 528 | + ciphers: 'DEFAULT:@SECLEVEL=0' |
| 529 | + } as ConnectionOptions); |
| 530 | + socket.destroy(); |
| 531 | + |
| 532 | + expect(setNoDelaySpy).to.have.been.calledWith(true); |
| 533 | + }); |
| 534 | + }); |
| 535 | + |
| 536 | + context('when tls is disabled', function () { |
| 537 | + it('calls setKeepAlive with default keepAliveInitialDelay', async function () { |
| 538 | + const socket = await makeSocket({ |
| 539 | + hostAddress: new HostAddress(`127.0.0.1:${tlsPort}`), |
| 540 | + tls: false |
| 541 | + } as ConnectionOptions); |
| 542 | + socket.destroy(); |
| 543 | + |
| 544 | + expect(setKeepAliveSpy).to.have.been.calledWith(true, DEFAULT_KEEP_ALIVE_INITIAL_DELAY_MS); |
| 545 | + }); |
| 546 | + |
| 547 | + it('calls setNoDelay with true by default', async function () { |
| 548 | + const socket = await makeSocket({ |
| 549 | + hostAddress: new HostAddress(`127.0.0.1:${tlsPort}`), |
| 550 | + tls: false |
| 551 | + } as ConnectionOptions); |
| 552 | + socket.destroy(); |
| 553 | + |
| 554 | + expect(setNoDelaySpy).to.have.been.calledWith(true); |
| 555 | + }); |
| 556 | + }); |
| 557 | + }); |
451 | 558 | }); |
0 commit comments