1// Flags: --expose-internals 2'use strict'; 3const common = require('../common'); 4const assert = require('assert'); 5const { internalBinding } = require('internal/test/binding'); 6const cares = internalBinding('cares_wrap'); 7 8// Stub `getaddrinfo` to *always* error. This has to be done before we load the 9// `dns` module to guarantee that the `dns` module uses the stub. 10cares.getaddrinfo = () => internalBinding('uv').UV_ENOMEM; 11 12const dns = require('dns'); 13const dnsPromises = dns.promises; 14 15{ 16 const err = { 17 code: 'ERR_INVALID_ARG_TYPE', 18 name: 'TypeError', 19 message: /^The "hostname" argument must be of type string\. Received type number/ 20 }; 21 22 assert.throws(() => dns.lookup(1, {}), err); 23 assert.throws(() => dnsPromises.lookup(1, {}), err); 24} 25 26// This also verifies different expectWarning notations. 27common.expectWarning({ 28 // For 'internal/test/binding' module. 29 'internal/test/binding': [ 30 'These APIs are for internal testing only. Do not use them.', 31 ], 32 // For calling `dns.lookup` with falsy `hostname`. 33 'DeprecationWarning': { 34 DEP0118: 'The provided hostname "false" is not a valid ' + 35 'hostname, and is supported in the dns module solely for compatibility.' 36 } 37}); 38 39assert.throws(() => { 40 dns.lookup(false, 'cb'); 41}, { 42 code: 'ERR_INVALID_ARG_TYPE', 43 name: 'TypeError' 44}); 45 46assert.throws(() => { 47 dns.lookup(false, 'options', 'cb'); 48}, { 49 code: 'ERR_INVALID_ARG_TYPE', 50 name: 'TypeError' 51}); 52 53{ 54 const err = { 55 code: 'ERR_INVALID_ARG_VALUE', 56 name: 'TypeError', 57 message: "The argument 'hints' is invalid. Received 100" 58 }; 59 const options = { 60 hints: 100, 61 family: 0, 62 all: false 63 }; 64 65 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 66 assert.throws(() => { 67 dns.lookup(false, options, common.mustNotCall()); 68 }, err); 69} 70 71{ 72 const family = 20; 73 const err = { 74 code: 'ERR_INVALID_ARG_VALUE', 75 name: 'TypeError', 76 message: `The property 'options.family' must be one of: 0, 4, 6. Received ${family}` 77 }; 78 const options = { 79 hints: 0, 80 family, 81 all: false 82 }; 83 84 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 85 assert.throws(() => { 86 dns.lookup(false, options, common.mustNotCall()); 87 }, err); 88} 89 90[1, 0n, 1n, '', '0', Symbol(), true, false, {}, [], () => {}] 91 .forEach((family) => { 92 const err = { code: 'ERR_INVALID_ARG_VALUE' }; 93 const options = { family }; 94 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 95 assert.throws(() => { 96 dns.lookup(false, options, common.mustNotCall()); 97 }, err); 98 }); 99[0n, 1n, '', '0', Symbol(), true, false].forEach((family) => { 100 const err = { code: 'ERR_INVALID_ARG_TYPE' }; 101 assert.throws(() => { dnsPromises.lookup(false, family); }, err); 102 assert.throws(() => { 103 dns.lookup(false, family, common.mustNotCall()); 104 }, err); 105}); 106assert.throws(() => dnsPromises.lookup(false, () => {}), 107 { code: 'ERR_INVALID_ARG_TYPE' }); 108 109[0n, 1n, '', '0', Symbol(), true, false, {}, [], () => {}].forEach((hints) => { 110 const err = { code: 'ERR_INVALID_ARG_TYPE' }; 111 const options = { hints }; 112 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 113 assert.throws(() => { 114 dns.lookup(false, options, common.mustNotCall()); 115 }, err); 116}); 117 118[0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((all) => { 119 const err = { code: 'ERR_INVALID_ARG_TYPE' }; 120 const options = { all }; 121 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 122 assert.throws(() => { 123 dns.lookup(false, options, common.mustNotCall()); 124 }, err); 125}); 126 127[0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((verbatim) => { 128 const err = { code: 'ERR_INVALID_ARG_TYPE' }; 129 const options = { verbatim }; 130 assert.throws(() => { dnsPromises.lookup(false, options); }, err); 131 assert.throws(() => { 132 dns.lookup(false, options, common.mustNotCall()); 133 }, err); 134}); 135 136(async function() { 137 let res; 138 139 res = await dnsPromises.lookup(false, { 140 hints: 0, 141 family: 0, 142 all: true 143 }); 144 assert.deepStrictEqual(res, []); 145 146 res = await dnsPromises.lookup('127.0.0.1', { 147 hints: 0, 148 family: 4, 149 all: true 150 }); 151 assert.deepStrictEqual(res, [{ address: '127.0.0.1', family: 4 }]); 152 153 res = await dnsPromises.lookup('127.0.0.1', { 154 hints: 0, 155 family: 4, 156 all: false 157 }); 158 assert.deepStrictEqual(res, { address: '127.0.0.1', family: 4 }); 159})().then(common.mustCall()); 160 161dns.lookup(false, { 162 hints: 0, 163 family: 0, 164 all: true 165}, common.mustSucceed((result, addressType) => { 166 assert.deepStrictEqual(result, []); 167 assert.strictEqual(addressType, undefined); 168})); 169 170dns.lookup('127.0.0.1', { 171 hints: 0, 172 family: 4, 173 all: true 174}, common.mustSucceed((result, addressType) => { 175 assert.deepStrictEqual(result, [{ 176 address: '127.0.0.1', 177 family: 4 178 }]); 179 assert.strictEqual(addressType, undefined); 180})); 181 182dns.lookup('127.0.0.1', { 183 hints: 0, 184 family: 4, 185 all: false 186}, common.mustSucceed((result, addressType) => { 187 assert.strictEqual(result, '127.0.0.1'); 188 assert.strictEqual(addressType, 4); 189})); 190 191let tickValue = 0; 192 193// Should fail due to stub. 194dns.lookup('example.com', common.mustCall((error, result, addressType) => { 195 assert(error); 196 assert.strictEqual(tickValue, 1); 197 assert.strictEqual(error.code, 'ENOMEM'); 198 const descriptor = Object.getOwnPropertyDescriptor(error, 'message'); 199 // The error message should be non-enumerable. 200 assert.strictEqual(descriptor.enumerable, false); 201})); 202 203// Make sure that the error callback is called on next tick. 204tickValue = 1; 205 206// Should fail due to stub. 207assert.rejects(dnsPromises.lookup('example.com'), 208 { code: 'ENOMEM', hostname: 'example.com' }); 209