diff --git a/src/cmap/auth/gssapi.ts b/src/cmap/auth/gssapi.ts index d18cb6b360..e421635169 100644 --- a/src/cmap/auth/gssapi.ts +++ b/src/cmap/auth/gssapi.ts @@ -166,7 +166,7 @@ export async function performGSSAPICanonicalizeHostName( try { // Perform a reverse ptr lookup on the ip address. - const results = await dns.promises.resolvePtr(address); + const results = await dns.promises.resolve(address, 'PTR'); // If the ptr did not error but had no results, return the host. return results.length > 0 ? results[0] : host; } catch { @@ -185,7 +185,7 @@ export async function performGSSAPICanonicalizeHostName( export async function resolveCname(host: string): Promise { // Attempt to resolve the host name try { - const results = await dns.promises.resolveCname(host); + const results = await dns.promises.resolve(host, 'CNAME'); // Get the first resolved host id return results.length > 0 ? results[0] : host; } catch { diff --git a/src/connection_string.ts b/src/connection_string.ts index df6dfc607a..0fb7394e77 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -41,17 +41,21 @@ const LB_REPLICA_SET_ERROR = 'loadBalanced option not supported with a replicaSe const LB_DIRECT_CONNECTION_ERROR = 'loadBalanced option not supported when directConnection is provided'; -function retryDNSTimeoutFor(api: 'resolveSrv'): (a: string) => Promise; -function retryDNSTimeoutFor(api: 'resolveTxt'): (a: string) => Promise; +function retryDNSTimeoutFor(rrtype: 'SRV'): (lookupAddress: string) => Promise; +function retryDNSTimeoutFor(rrtype: 'TXT'): (lookupAddress: string) => Promise; function retryDNSTimeoutFor( - api: 'resolveSrv' | 'resolveTxt' -): (a: string) => Promise { + rrtype: 'SRV' | 'TXT' +): (lookupAddress: string) => Promise { + const resolve = + rrtype === 'SRV' + ? (address: string) => dns.promises.resolve(address, 'SRV') + : (address: string) => dns.promises.resolve(address, 'TXT'); return async function dnsReqRetryTimeout(lookupAddress: string) { try { - return await dns.promises[api](lookupAddress); + return await resolve(lookupAddress); } catch (firstDNSError) { if (firstDNSError.code === dns.TIMEOUT) { - return await dns.promises[api](lookupAddress); + return await resolve(lookupAddress); } else { throw firstDNSError; } @@ -59,8 +63,8 @@ function retryDNSTimeoutFor( }; } -const resolveSrv = retryDNSTimeoutFor('resolveSrv'); -const resolveTxt = retryDNSTimeoutFor('resolveTxt'); +const resolveSrv = retryDNSTimeoutFor('SRV'); +const resolveTxt = retryDNSTimeoutFor('TXT'); /** * Lookup a `mongodb+srv` connection string, combine the parts and reparse it as a normal diff --git a/src/sdam/srv_polling.ts b/src/sdam/srv_polling.ts index 583c82d139..cfc4779cf2 100644 --- a/src/sdam/srv_polling.ts +++ b/src/sdam/srv_polling.ts @@ -116,7 +116,7 @@ export class SrvPoller extends TypedEventEmitter { let srvRecords; try { - srvRecords = await dns.promises.resolveSrv(this.srvAddress); + srvRecords = await dns.promises.resolve(this.srvAddress, 'SRV'); } catch { this.failure(); return; diff --git a/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts b/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts index 15ad016cc3..cc0981fa49 100644 --- a/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts +++ b/test/integration/initial-dns-seedlist-discovery/dns_seedlist.test.ts @@ -23,6 +23,7 @@ describe('DNS timeout errors', () => { beforeEach(async function () { client = new MongoClient(CONNECTION_STRING, { serverSelectionTimeoutMS: 2000, tls: false }); + stub = sinon.stub(dns.promises, 'resolve').callThrough(); }); afterEach(async function () { @@ -31,134 +32,108 @@ describe('DNS timeout errors', () => { await client.close(); }); - const restoreDNS = - api => - async (...args) => { - sinon.restore(); - return await dns.promises[api](...args); - }; + const restoreDNS = rrtype => async hostname => { + stub.restore(); + return await dns.promises.resolve(hostname, rrtype); + }; describe('when SRV record look up times out', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveSrv') + stub + .withArgs(sinon.match.string, 'SRV') .onFirstCall() .rejects(new DNSTimeoutError()) .onSecondCall() - .callsFake(restoreDNS('resolveSrv')); - }); - - afterEach(async function () { - sinon.restore(); + .callsFake(restoreDNS('SRV')); }); it('retries timeout error', metadata, async () => { await client.connect(); - expect(stub).to.have.been.calledTwice; + expect(stub.withArgs(sinon.match.string, 'SRV')).to.have.been.calledTwice; }); }); describe('when TXT record look up times out', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveTxt') + stub + .withArgs(sinon.match.string, 'TXT') .onFirstCall() .rejects(new DNSTimeoutError()) .onSecondCall() - .callsFake(restoreDNS('resolveTxt')); - }); - - afterEach(async function () { - sinon.restore(); + .callsFake(restoreDNS('TXT')); }); it('retries timeout error', metadata, async () => { await client.connect(); - expect(stub).to.have.been.calledTwice; + expect(stub.withArgs(sinon.match.string, 'TXT')).to.have.been.calledTwice; }); }); describe('when SRV record look up times out twice', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveSrv') + stub + .withArgs(sinon.match.string, 'SRV') .onFirstCall() .rejects(new DNSTimeoutError()) .onSecondCall() .rejects(new DNSTimeoutError()); }); - afterEach(async function () { - sinon.restore(); - }); - it('throws timeout error', metadata, async () => { const error = await client.connect().catch(error => error); expect(error).to.be.instanceOf(DNSTimeoutError); - expect(stub).to.have.been.calledTwice; + expect(stub.withArgs(sinon.match.string, 'SRV')).to.have.been.calledTwice; }); }); describe('when TXT record look up times out twice', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveTxt') + stub + .withArgs(sinon.match.string, 'TXT') .onFirstCall() .rejects(new DNSTimeoutError()) .onSecondCall() .rejects(new DNSTimeoutError()); }); - afterEach(async function () { - sinon.restore(); - }); - it('throws timeout error', metadata, async () => { const error = await client.connect().catch(error => error); expect(error).to.be.instanceOf(DNSTimeoutError); - expect(stub).to.have.been.calledTwice; + expect(stub.withArgs(sinon.match.string, 'TXT')).to.have.been.calledTwice; }); }); describe('when SRV record look up throws a non-timeout error', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveSrv') + stub + .withArgs(sinon.match.string, 'SRV') .onFirstCall() .rejects(new DNSSomethingError()) .onSecondCall() - .callsFake(restoreDNS('resolveSrv')); - }); - - afterEach(async function () { - sinon.restore(); + .callsFake(restoreDNS('SRV')); }); it('throws that error', metadata, async () => { const error = await client.connect().catch(error => error); expect(error).to.be.instanceOf(DNSSomethingError); - expect(stub).to.have.been.calledOnce; + expect(stub.withArgs(sinon.match.string, 'SRV')).to.have.been.calledOnce; }); }); describe('when TXT record look up throws a non-timeout error', () => { beforeEach(() => { - stub = sinon - .stub(dns.promises, 'resolveTxt') + stub + .withArgs(sinon.match.string, 'TXT') .onFirstCall() .rejects(new DNSSomethingError()) .onSecondCall() - .callsFake(restoreDNS('resolveTxt')); - }); - - afterEach(async function () { - sinon.restore(); + .callsFake(restoreDNS('TXT')); }); it('throws that error', metadata, async () => { const error = await client.connect().catch(error => error); expect(error).to.be.instanceOf(DNSSomethingError); - expect(stub).to.have.been.calledOnce; + expect(stub.withArgs(sinon.match.string, 'TXT')).to.have.been.calledOnce; }); }); }); diff --git a/test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts b/test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts index c36e675ae5..dc879ecb08 100644 --- a/test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts +++ b/test/integration/initial-dns-seedlist-discovery/initial_dns_seedlist_discovery.prose.test.ts @@ -23,7 +23,8 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { beforeEach(async function () { // this fn stubs DNS resolution to always pass - so we are only checking pre-DNS validation - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + const stub = sinon.stub(dns.promises, 'resolve'); + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'resolved.mongo.localhost', @@ -34,7 +35,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { ]; }); - sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => { + stub.withArgs(sinon.match.string, 'TXT').callsFake(async () => { throw { code: 'ENODATA' }; }); @@ -84,9 +85,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { * - the SRV mongodb+srv://blogs.mongodb.com resolving to blogs.evil.com * Remember, the domain of an SRV with one or two . separated parts is the SRVs entire hostname. */ + let stub; beforeEach(async function () { - sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => { + stub = sinon.stub(dns.promises, 'resolve'); + stub.withArgs(sinon.match.string, 'TXT').callsFake(async () => { throw { code: 'ENODATA' }; }); }); @@ -96,7 +99,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with one domain level causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'localhost.mongodb', @@ -115,7 +118,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with two domain levels causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'test_1.evil.local', // this string only ends with part of the domain, not all of it! @@ -134,7 +137,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with three or more domain levels causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'blogs.evil.com', @@ -166,8 +169,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { context( 'when given a host from DNS resolution that is identical to the original SRVs hostname', function () { + let stub; + beforeEach(async function () { - sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => { + stub = sinon.stub(dns.promises, 'resolve'); + stub.withArgs(sinon.match.string, 'TXT').callsFake(async () => { throw { code: 'ENODATA' }; }); }); @@ -177,7 +183,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with one domain level causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'localhost', @@ -198,7 +204,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with two domain levels causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'mongo.local', @@ -233,8 +239,11 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { context( 'when given a returned address that does NOT share the domain name of the SRV record because its missing a `.`', function () { + let stub; + beforeEach(async function () { - sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => { + stub = sinon.stub(dns.promises, 'resolve'); + stub.withArgs(sinon.match.string, 'TXT').callsFake(async () => { throw { code: 'ENODATA' }; }); }); @@ -244,7 +253,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with one domain level causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'test_1.cluster_1localhost', @@ -263,7 +272,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with two domain levels causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'test_1.my_hostmongo.local', @@ -282,7 +291,7 @@ describe('Initial DNS Seedlist Discovery (Prose Tests)', () => { }); it('an SRV with three domain levels causes a runtime error', async function () { - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + stub.withArgs(sinon.match.string, 'SRV').callsFake(async () => { return [ { name: 'cluster.testmongodb.com', diff --git a/test/manual/kerberos.test.ts b/test/manual/kerberos.test.ts index 3260f455eb..9ed66a04dd 100644 --- a/test/manual/kerberos.test.ts +++ b/test/manual/kerberos.test.ts @@ -17,14 +17,13 @@ async function verifyKerberosAuthentication(client) { } describe('Kerberos', function () { - let resolvePtrSpy; - let resolveCnameSpy; + let resolveStub; + let lookupStub; let client; beforeEach(() => { - sinon.spy(dns, 'lookup'); - resolvePtrSpy = sinon.spy(dns, 'resolvePtr'); - resolveCnameSpy = sinon.spy(dns, 'resolveCname'); + lookupStub = sinon.stub(dns, 'lookup').callThrough(); + resolveStub = sinon.stub(dns, 'resolve').callThrough(); }); afterEach(function () { @@ -65,7 +64,7 @@ describe('Kerberos', function () { `${krb5Uri}&authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:forward&maxPoolSize=1` ); await client.connect(); - expect(dns.resolveCname).to.be.calledOnceWith(host); + expect(resolveStub.withArgs(sinon.match.any, 'CNAME')).to.be.calledOnceWith(host); await verifyKerberosAuthentication(client); }); }); @@ -77,9 +76,10 @@ describe('Kerberos', function () { `${krb5Uri}&authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${option}&maxPoolSize=1` ); await client.connect(); - expect(dns.resolveCname).to.not.be.called; + + expect(resolveStub.withArgs(sinon.match.any, 'CNAME')).to.not.be.called; // There are 2 calls to establish connection, however they use the callback form of dns.lookup - expect(dns.lookup).to.not.be.called; + expect(lookupStub).to.not.be.called; await verifyKerberosAuthentication(client); }); }); @@ -88,28 +88,23 @@ describe('Kerberos', function () { for (const option of [true, 'forwardAndReverse']) { context(`when the value is ${option}`, function () { context('when the reverse lookup succeeds', function () { - beforeEach(function () { - resolvePtrSpy.restore(); - sinon.stub(dns, 'resolvePtr').resolves([host]); - }); - it('authenticates with a forward dns lookup and a reverse ptr lookup', async function () { client = new MongoClient( `${krb5Uri}&authMechanismProperties=SERVICE_NAME:mongodb,CANONICALIZE_HOST_NAME:${option}&maxPoolSize=1` ); await client.connect(); + // There are 2 calls to establish connection, however they use the callback form of dns.lookup // 1 dns.promises.lookup call in canonicalization. - expect(dns.lookup).to.be.calledOnce; - expect(dns.resolvePtr).to.be.calledOnce; + expect(lookupStub).to.be.calledOnce; + expect(resolveStub.withArgs(sinon.match.any, 'PTR')).to.be.calledOnce; await verifyKerberosAuthentication(client); }); }); context('when the reverse lookup is empty', function () { beforeEach(function () { - resolvePtrSpy.restore(); - sinon.stub(dns, 'resolvePtr').resolves([]); + resolveStub.withArgs(sinon.match.string, 'PTR').resolves([]); }); it('authenticates with a fallback cname lookup', async function () { @@ -120,19 +115,18 @@ describe('Kerberos', function () { await client.connect(); // There are 2 calls to establish connection, however they use the callback form of dns.lookup // 1 dns.promises.lookup call in canonicalization. - expect(dns.lookup).to.be.calledOnce; + expect(lookupStub).to.be.calledOnce; // This fails. - expect(dns.resolvePtr).to.be.calledOnce; + expect(resolveStub.withArgs(sinon.match.string, 'PTR')).to.be.calledOnce; // Expect the fallback to the host name. - expect(dns.resolveCname).to.not.be.called; + expect(resolveStub.withArgs(sinon.match.string, 'CNAME')).to.not.be.called; await verifyKerberosAuthentication(client); }); }); context('when the reverse lookup fails', function () { beforeEach(function () { - resolvePtrSpy.restore(); - sinon.stub(dns, 'resolvePtr').rejects(new Error('not found')); + resolveStub.withArgs(sinon.match.string, 'PTR').rejects(new Error('not found')); }); it('authenticates with a fallback cname lookup', async function () { @@ -143,19 +137,18 @@ describe('Kerberos', function () { await client.connect(); // There are 2 calls to establish connection, however they use the callback form of dns.lookup // 1 dns.promises.lookup call in canonicalization. - expect(dns.lookup).to.be.calledOnce; + expect(lookupStub).to.be.calledOnce; // This fails. - expect(dns.resolvePtr).to.be.calledOnce; + expect(resolveStub.withArgs(sinon.match.string, 'PTR')).to.be.calledOnce; // Expect the fallback to be called. - expect(dns.resolveCname).to.be.calledOnceWith(host); + expect(resolveStub.withArgs(sinon.match.string, 'CNAME')).to.be.calledOnceWith(host); await verifyKerberosAuthentication(client); }); }); context('when the cname lookup fails', function () { beforeEach(function () { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').rejects(new Error('not found')); + resolveStub.withArgs(sinon.match.string, 'CNAME').rejects(new Error('not found')); }); it('authenticates with a fallback host name', async function () { @@ -165,19 +158,18 @@ describe('Kerberos', function () { await client.connect(); // There are 2 calls to establish connection, however they use the callback form of dns.lookup // 1 dns.promises.lookup call in canonicalization. - expect(dns.lookup).to.be.calledOnce; + expect(lookupStub).to.be.calledOnce; // This fails. - expect(dns.resolvePtr).to.be.calledOnce; + expect(resolveStub.withArgs(sinon.match.string, 'PTR')).to.be.calledOnce; // Expect the fallback to be called. - expect(dns.resolveCname).to.be.calledOnceWith(host); + expect(resolveStub.withArgs(sinon.match.string, 'CNAME')).to.be.calledOnceWith(host); await verifyKerberosAuthentication(client); }); }); context('when the cname lookup is empty', function () { beforeEach(function () { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').resolves([]); + resolveStub.withArgs(sinon.match.string, 'CNAME').rejects([]); }); it('authenticates with a fallback host name', async function () { @@ -187,11 +179,11 @@ describe('Kerberos', function () { await client.connect(); // There are 2 calls to establish connection, however they use the callback form of dns.lookup // 1 dns.promises.lookup call in canonicalization. - expect(dns.lookup).to.be.calledOnce; + expect(lookupStub).to.be.calledOnce; // This fails. - expect(dns.resolvePtr).to.be.calledOnce; + expect(resolveStub.withArgs(sinon.match.string, 'PTR')).to.be.calledOnce; // Expect the fallback to be called. - expect(dns.resolveCname).to.be.calledOnceWith(host); + expect(resolveStub.withArgs(sinon.match.string, 'CNAME')).to.be.calledOnceWith(host); await verifyKerberosAuthentication(client); }); }); diff --git a/test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts b/test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts index 4db98a5c7d..26997a23bf 100644 --- a/test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts +++ b/test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts @@ -282,7 +282,7 @@ describe('Polling Srv Records for Mongos Discovery', () => { initialRecords ??= mockRecords; // first call is for the driver initial connection // second call will check the poller - resolveSrvStub = sinon.stub(dns.promises, 'resolveSrv').callsFake(async address => { + resolveSrvStub = sinon.stub(dns.promises, 'resolve').callsFake(async address => { expect(address).to.equal(`_${srvServiceName}._tcp.test.mock.test.build.10gen.cc`); if (initialDNSLookup) { initialDNSLookup = false; diff --git a/test/unit/cmap/auth/gssapi.test.ts b/test/unit/cmap/auth/gssapi.test.ts index 9df2500b8e..b0a6fe4eaf 100644 --- a/test/unit/cmap/auth/gssapi.test.ts +++ b/test/unit/cmap/auth/gssapi.test.ts @@ -10,13 +10,11 @@ import { describe('GSSAPI', () => { let lookupSpy; - let resolvePtrSpy; - let resolveCnameSpy; + let resolveSpy; beforeEach(() => { lookupSpy = sinon.spy(dns, 'lookup'); - resolvePtrSpy = sinon.spy(dns, 'resolvePtr'); - resolveCnameSpy = sinon.spy(dns, 'resolveCname'); + resolveSpy = sinon.spy(dns, 'resolve'); }); afterEach(() => { @@ -34,8 +32,8 @@ describe('GSSAPI', () => { }); expect(host).to.equal(hostName); expect(dns.lookup).to.not.be.called; - expect(dns.resolvePtr).to.not.be.called; - expect(dns.resolveCname).to.not.be.called; + expect(dns.resolve.withArgs(sinon.match.string, 'PTR')).to.not.be.called; + expect(dns.resolve.withArgs(sinon.match.string, 'CNAME')).to.not.be.called; }); }); } @@ -44,8 +42,8 @@ describe('GSSAPI', () => { const resolved = '10gen.cc'; beforeEach(() => { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').resolves([resolved]); + resolveSpy.restore(); + sinon.stub(dns, 'resolve').withArgs(sinon.match.string, 'CNAME').resolves([resolved]); }); it('performs a cname lookup', async () => { @@ -54,8 +52,8 @@ describe('GSSAPI', () => { }); expect(host).to.equal(resolved); expect(dns.lookup).to.not.be.called; - expect(dns.resolvePtr).to.not.be.called; - expect(dns.resolveCname).to.be.calledOnceWith(hostName); + expect(dns.resolve.withArgs(sinon.match.string, 'PTR')).to.not.be.called; + expect(dns.resolve).to.be.calledOnceWith(hostName, 'CNAME'); }); }); @@ -73,9 +71,9 @@ describe('GSSAPI', () => { beforeEach(() => { lookupSpy.restore(); - resolvePtrSpy.restore(); + resolveSpy.restore(); sinon.stub(dns, 'lookup').resolves(lookedUp); - sinon.stub(dns, 'resolvePtr').resolves([resolved]); + sinon.stub(dns, 'resolve').withArgs(sinon.match.string, 'PTR').resolves([resolved]); }); it('uses the reverse lookup host', async () => { @@ -84,8 +82,8 @@ describe('GSSAPI', () => { }); expect(host).to.equal(resolved); expect(dns.lookup).to.be.calledOnceWith(hostName); - expect(dns.resolvePtr).to.be.calledOnceWith(lookedUp.address); - expect(dns.resolveCname).to.not.be.called; + expect(dns.resolve).to.be.calledOnceWith(lookedUp.address, 'PTR'); + expect(dns.resolve).to.not.be.calledOnceWith(lookedUp.address, 'CNAME'); }); }); @@ -94,9 +92,12 @@ describe('GSSAPI', () => { beforeEach(() => { lookupSpy.restore(); - resolvePtrSpy.restore(); + resolveSpy.restore(); sinon.stub(dns, 'lookup').resolves(lookedUp); - sinon.stub(dns, 'resolvePtr').resolves([resolved, 'example.com']); + sinon + .stub(dns, 'resolve') + .withArgs(sinon.match.string, 'PTR') + .resolves([resolved, 'example.com']); }); it('uses the first found reverse lookup host', async () => { @@ -105,8 +106,8 @@ describe('GSSAPI', () => { }); expect(host).to.equal(resolved); expect(dns.lookup).to.be.calledOnceWith(hostName); - expect(dns.resolvePtr).to.be.calledOnceWith(lookedUp.address); - expect(dns.resolveCname).to.not.be.called; + expect(dns.resolve).to.be.calledOnceWith(lookedUp.address, 'PTR'); + expect(dns.resolve).to.not.be.calledOnceWith(sinon.match.string, 'CNAME'); }); }); }); @@ -116,11 +117,11 @@ describe('GSSAPI', () => { beforeEach(() => { lookupSpy.restore(); - resolvePtrSpy.restore(); - resolveCnameSpy.restore(); + resolveSpy.restore(); sinon.stub(dns, 'lookup').resolves(lookedUp); - sinon.stub(dns, 'resolvePtr').rejects(new Error('failed')); - sinon.stub(dns, 'resolveCname').resolves([cname]); + const stub = sinon.stub(dns, 'resolve'); + stub.withArgs(sinon.match.string, 'PTR').rejects(new Error('failed')); + stub.withArgs(sinon.match.string, 'CNAME').resolves([cname]); }); it('falls back to a cname lookup', async () => { @@ -130,17 +131,17 @@ describe('GSSAPI', () => { expect(host).to.equal(cname); expect(dns.lookup).to.be.calledOnceWith(hostName); - expect(dns.resolvePtr).to.be.calledOnceWith(lookedUp.address); - expect(dns.resolveCname).to.be.calledWith(hostName); + expect(dns.resolve).to.be.calledWith(lookedUp.address, 'PTR'); + expect(dns.resolve).to.be.calledWith(hostName, 'CNAME'); }); }); context('when the reverse lookup is empty', () => { beforeEach(() => { lookupSpy.restore(); - resolvePtrSpy.restore(); + resolveSpy.restore(); sinon.stub(dns, 'lookup').resolves(lookedUp); - sinon.stub(dns, 'resolvePtr').resolves([]); + sinon.stub(dns, 'resolve').withArgs(sinon.match.string, 'PTR').resolves([]); }); it('uses the provided host', async () => { @@ -149,8 +150,8 @@ describe('GSSAPI', () => { }); expect(host).to.equal(hostName); expect(dns.lookup).to.be.calledOnceWith(hostName); - expect(dns.resolvePtr).to.be.calledOnceWith(lookedUp.address); - expect(dns.resolveCname).to.not.be.called; + expect(dns.resolve).to.be.calledOnceWith(lookedUp.address, 'PTR'); + expect(dns.resolve).to.not.be.calledWith(sinon.match.string, 'CNAME'); }); }); }); @@ -168,8 +169,8 @@ describe('GSSAPI', () => { expect(error.message).to.equal('failed'); expect(dns.lookup).to.be.calledOnceWith(hostName); - expect(dns.resolvePtr).to.not.be.called; - expect(dns.resolveCname).to.not.be.called; + expect(dns.resolve).to.not.be.calledWith(sinon.match.string, 'PTR'); + expect(dns.resolve).to.not.be.calledWith(sinon.match.string, 'CNAME'); }); }); }); @@ -181,14 +182,17 @@ describe('GSSAPI', () => { const hostName = 'example.com'; beforeEach(() => { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').rejects(new Error('failed')); + resolveSpy.restore(); + sinon + .stub(dns, 'resolve') + .withArgs(sinon.match.string, 'CNAME') + .rejects(new Error('failed')); }); it('falls back to the provided host name', async () => { const host = await resolveCname(hostName); expect(host).to.equal(hostName); - expect(dns.resolveCname).to.be.calledOnceWith(hostName); + expect(dns.resolve).to.be.calledOnceWith(hostName, 'CNAME'); }); }); @@ -198,14 +202,14 @@ describe('GSSAPI', () => { const resolved = '10gen.cc'; beforeEach(() => { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').resolves([resolved]); + resolveSpy.restore(); + sinon.stub(dns, 'resolve').withArgs(sinon.match.string, 'CNAME').resolves([resolved]); }); it('uses the result', async () => { const host = await resolveCname(hostName); expect(host).to.equal(resolved); - expect(dns.resolveCname).to.be.calledOnceWith(hostName); + expect(dns.resolve).to.be.calledOnceWith(hostName, 'CNAME'); }); }); @@ -214,14 +218,17 @@ describe('GSSAPI', () => { const resolved = '10gen.cc'; beforeEach(() => { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').resolves([resolved, hostName]); + resolveSpy.restore(); + sinon + .stub(dns, 'resolve') + .withArgs(sinon.match.string, 'CNAME') + .resolves([resolved, hostName]); }); it('uses the first result', async () => { const host = await resolveCname(hostName); expect(host).to.equal(resolved); - expect(dns.resolveCname).to.be.calledOnceWith(hostName); + expect(dns.resolve).to.be.calledOnceWith(hostName, 'CNAME'); }); }); }); @@ -230,14 +237,14 @@ describe('GSSAPI', () => { const hostName = 'example.com'; beforeEach(() => { - resolveCnameSpy.restore(); - sinon.stub(dns, 'resolveCname').resolves([]); + resolveSpy.restore(); + sinon.stub(dns, 'resolve').withArgs(sinon.match.string, 'CNAME').resolves([]); }); it('falls back to using the provided host', async () => { const host = await resolveCname(hostName); expect(host).to.equal(hostName); - expect(dns.resolveCname).to.be.calledOnceWith(hostName); + expect(dns.resolve).to.be.calledOnceWith(hostName, 'CNAME'); }); }); }); diff --git a/test/unit/connection_string.test.ts b/test/unit/connection_string.test.ts index 7b3cfdb9ed..5ebe37a5bb 100644 --- a/test/unit/connection_string.test.ts +++ b/test/unit/connection_string.test.ts @@ -631,13 +631,14 @@ describe('Connection String', function () { const mockRecord: string[][] = [[txtRecord]]; - // first call is for stubbing resolveSrv - // second call is for stubbing resolveTxt - sinon.stub(dns.promises, 'resolveSrv').callsFake(async () => { + // first call is for stubbing resolve + // second call is for stubbing resolve + const stub = sinon.stub(dns.promises, 'resolve'); + stub.withArgs(sinon.match.any, 'SRV').callsFake(async () => { return mockAddress; }); - sinon.stub(dns.promises, 'resolveTxt').callsFake(async () => { + stub.withArgs(sinon.match.any, 'TXT').callsFake(async () => { return mockRecord; }); } diff --git a/test/unit/sdam/srv_polling.test.ts b/test/unit/sdam/srv_polling.test.ts index f38dfd646d..7d2e9915c4 100644 --- a/test/unit/sdam/srv_polling.test.ts +++ b/test/unit/sdam/srv_polling.test.ts @@ -28,9 +28,9 @@ describe('Mongos SRV Polling', function () { function stubDns(err: Error | null, records?: dns.SrvRecord[]) { if (err) { - sinon.stub(dns.promises, 'resolveSrv').rejects(err); + sinon.stub(dns.promises, 'resolve').rejects(err); } else { - sinon.stub(dns.promises, 'resolveSrv').resolves(records); + sinon.stub(dns.promises, 'resolve').resolves(records); } } @@ -93,13 +93,13 @@ describe('Mongos SRV Polling', function () { it('should poll dns srv records', async function () { const poller = new SrvPoller({ srvHost: SRV_HOST }); - sinon.stub(dns.promises, 'resolveSrv').resolves([srvRecord('iLoveJavascript.lots')]); + sinon.stub(dns.promises, 'resolve').resolves([srvRecord('iLoveJavascript.lots')]); await poller._poll(); clearTimeout(poller._timeout); - expect(dns.promises.resolveSrv).to.have.been.calledOnce.and.to.have.been.calledWith( + expect(dns.promises.resolve).to.have.been.calledOnce.and.to.have.been.calledWith( `_mongodb._tcp.${SRV_HOST}` ); });