File
Blob: src/workerd/api/node/tests/dns-nodejs-test.js
| 1 | // Copyright (c) 2017-2022 Cloudflare, Inc. |
| 2 | // Licensed under the Apache 2.0 license found in the LICENSE file or at: |
| 3 | // https://opensource.org/licenses/Apache-2.0 |
| 4 | // Copyright Joyent and Node contributors. All rights reserved. MIT license. |
| 5 | import dns from 'node:dns'; |
| 6 | import dnsPromises from 'node:dns/promises'; |
| 7 | import { strictEqual, ok, deepStrictEqual, throws } from 'node:assert'; |
| 8 | import { inspect } from 'node:util'; |
| 9 | |
| 10 | // Taken from Node.js |
| 11 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/common/internet.js |
| 12 | const addresses = { |
| 13 | // A generic host that has registered common DNS records, |
| 14 | // supports both IPv4 and IPv6, and provides basic HTTP/HTTPS services |
| 15 | INET_HOST: 'nodejs.org', |
| 16 | // A host that provides IPv4 services |
| 17 | INET4_HOST: 'nodejs.org', |
| 18 | // A host that provides IPv6 services |
| 19 | INET6_HOST: 'nodejs.org', |
| 20 | // An accessible IPv4 IP, |
| 21 | // defaults to the Google Public DNS IPv4 address |
| 22 | INET4_IP: '8.8.8.8', |
| 23 | // An accessible IPv6 IP, |
| 24 | // defaults to the Google Public DNS IPv6 address |
| 25 | INET6_IP: '2001:4860:4860::8888', |
| 26 | // An invalid host that cannot be resolved |
| 27 | // See https://tools.ietf.org/html/rfc2606#section-2 |
| 28 | INVALID_HOST: 'something.invalid', |
| 29 | // A host with MX records registered |
| 30 | MX_HOST: 'nodejs.org', |
| 31 | // On some systems, .invalid returns a server failure/try again rather than |
| 32 | // record not found. Use this to guarantee record not found. |
| 33 | NOT_FOUND: 'come.on.fhqwhgads.test', |
| 34 | // A host with SRV records registered |
| 35 | SRV_HOST: '_caldav._tcp.google.com', |
| 36 | // A host with PTR records registered |
| 37 | PTR_HOST: '8.8.8.8.in-addr.arpa', |
| 38 | // A host with NAPTR records registered |
| 39 | NAPTR_HOST: 'sip2sip.info', |
| 40 | // A host with SOA records registered |
| 41 | SOA_HOST: 'nodejs.org', |
| 42 | // A host with CAA record registered |
| 43 | CAA_HOST: 'google.com', |
| 44 | // A host with CNAME records registered |
| 45 | CNAME_HOST: 'blog.nodejs.org', |
| 46 | // A host with NS records registered |
| 47 | NS_HOST: 'nodejs.org', |
| 48 | // A host with TXT records registered |
| 49 | TXT_HOST: 'nodejs.org', |
| 50 | // An accessible IPv4 DNS server |
| 51 | DNS4_SERVER: '8.8.8.8', |
| 52 | // An accessible IPv4 DNS server |
| 53 | DNS6_SERVER: '2001:4860:4860::8888', |
| 54 | }; |
| 55 | |
| 56 | export const functionsExist = { |
| 57 | async test() { |
| 58 | const syncFns = [ |
| 59 | 'lookup', |
| 60 | 'lookupService', |
| 61 | 'resolve', |
| 62 | 'resolve4', |
| 63 | 'resolve6', |
| 64 | 'resolveAny', |
| 65 | 'resolveCname', |
| 66 | 'resolveCaa', |
| 67 | 'resolveMx', |
| 68 | 'resolveNaptr', |
| 69 | 'resolveNs', |
| 70 | 'resolvePtr', |
| 71 | 'resolveSoa', |
| 72 | 'resolveSrv', |
| 73 | 'setDefaultResultOrder', |
| 74 | 'getDefaultResultOrder', |
| 75 | 'setServers', |
| 76 | ]; |
| 77 | |
| 78 | for (const fn of syncFns) { |
| 79 | strictEqual(typeof dns[fn], 'function'); |
| 80 | } |
| 81 | |
| 82 | ok(dns.promises !== undefined); |
| 83 | }, |
| 84 | }; |
| 85 | |
| 86 | export const errorCodesExist = { |
| 87 | async test() { |
| 88 | strictEqual(typeof dns.NODATA, 'string'); |
| 89 | strictEqual(typeof dnsPromises.NODATA, 'string'); |
| 90 | }, |
| 91 | }; |
| 92 | |
| 93 | // Tests are taken from |
| 94 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/internet/test-dns.js#L483 |
| 95 | export const resolveTxt = { |
| 96 | async test() { |
| 97 | function validateResult(result) { |
| 98 | ok( |
| 99 | result.length > 0, |
| 100 | `Result length should be greater than 0 but got ${inspect(result)}` |
| 101 | ); |
| 102 | ok(Array.isArray(result[0])); |
| 103 | ok( |
| 104 | result.some((record) => record[0].startsWith('v=spf1')), |
| 105 | `Expected SPF record but got ${inspect(result[0])}` |
| 106 | ); |
| 107 | } |
| 108 | |
| 109 | validateResult(await dnsPromises.resolveTxt(addresses.TXT_HOST)); |
| 110 | |
| 111 | { |
| 112 | // Callback API |
| 113 | const { promise, resolve, reject } = Promise.withResolvers(); |
| 114 | dns.resolveTxt(addresses.TXT_HOST, (error, results) => { |
| 115 | if (error) { |
| 116 | reject(error); |
| 117 | return; |
| 118 | } |
| 119 | validateResult(results); |
| 120 | resolve(); |
| 121 | }); |
| 122 | await promise; |
| 123 | } |
| 124 | }, |
| 125 | }; |
| 126 | |
| 127 | // Tests are taken from |
| 128 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/internet/test-dns.js#L402 |
| 129 | export const resolveCaa = { |
| 130 | async test() { |
| 131 | function validateResult(result) { |
| 132 | ok(Array.isArray(result), `expected array, got ${inspect(result)}`); |
| 133 | strictEqual(result.length, 1); |
| 134 | strictEqual(typeof result[0].critical, 'number'); |
| 135 | strictEqual(result[0].critical, 0); |
| 136 | strictEqual(result[0].issue, 'pki.goog'); |
| 137 | } |
| 138 | |
| 139 | validateResult(await dnsPromises.resolveCaa(addresses.CAA_HOST)); |
| 140 | }, |
| 141 | }; |
| 142 | |
| 143 | // Tests are taken from |
| 144 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/internet/test-dns.js#L142 |
| 145 | export const resolveMx = { |
| 146 | async test() { |
| 147 | function validateResult(result) { |
| 148 | ok(result.length > 0); |
| 149 | |
| 150 | for (const item of result) { |
| 151 | strictEqual(typeof item, 'object'); |
| 152 | ok(item.exchange); |
| 153 | strictEqual(typeof item.exchange, 'string'); |
| 154 | strictEqual(typeof item.priority, 'number'); |
| 155 | } |
| 156 | } |
| 157 | validateResult(await dnsPromises.resolveMx(addresses.MX_HOST)); |
| 158 | }, |
| 159 | }; |
| 160 | |
| 161 | // Tests are taken from |
| 162 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L442 |
| 163 | export const resolveCname = { |
| 164 | async test() { |
| 165 | function validateResult(result) { |
| 166 | ok(result.length > 0); |
| 167 | |
| 168 | for (const item of result) { |
| 169 | ok(item); |
| 170 | strictEqual(typeof item, 'string'); |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | validateResult(await dnsPromises.resolveCname(addresses.CNAME_HOST)); |
| 175 | }, |
| 176 | }; |
| 177 | |
| 178 | // Tests are taken from |
| 179 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L184 |
| 180 | export const resolveNs = { |
| 181 | async test() { |
| 182 | function validateResult(result) { |
| 183 | ok(result.length > 0); |
| 184 | |
| 185 | for (const item of result) { |
| 186 | ok(item); |
| 187 | strictEqual(typeof item, 'string'); |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | validateResult(await dnsPromises.resolveNs(addresses.NS_HOST)); |
| 192 | }, |
| 193 | }; |
| 194 | |
| 195 | // Tests are taken from |
| 196 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L268 |
| 197 | export const resolvePtr = { |
| 198 | async test() { |
| 199 | function validateResult(result) { |
| 200 | ok(result.length > 0); |
| 201 | |
| 202 | for (const item of result) { |
| 203 | ok(item); |
| 204 | strictEqual(typeof item, 'string'); |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | validateResult(await dnsPromises.resolvePtr(addresses.PTR_HOST)); |
| 209 | }, |
| 210 | }; |
| 211 | |
| 212 | // Tests are taken from |
| 213 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L224 |
| 214 | export const resolveSrv = { |
| 215 | async test() { |
| 216 | function validateResult(result) { |
| 217 | ok(result.length > 0); |
| 218 | |
| 219 | for (const item of result) { |
| 220 | strictEqual(typeof item, 'object'); |
| 221 | ok(item.name); |
| 222 | strictEqual(typeof item.name, 'string'); |
| 223 | strictEqual(typeof item.port, 'number'); |
| 224 | strictEqual(typeof item.priority, 'number'); |
| 225 | strictEqual(typeof item.weight, 'number'); |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | validateResult(await dnsPromises.resolveSrv(addresses.SRV_HOST)); |
| 230 | }, |
| 231 | }; |
| 232 | |
| 233 | // Tests are taken from |
| 234 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L353 |
| 235 | export const resolveSoa = { |
| 236 | async test() { |
| 237 | function validateResult(result) { |
| 238 | strictEqual(typeof result, 'object'); |
| 239 | strictEqual(typeof result.nsname, 'string'); |
| 240 | ok(result.nsname.length > 0); |
| 241 | strictEqual(typeof result.hostmaster, 'string'); |
| 242 | ok(result.hostmaster.length > 0); |
| 243 | strictEqual(typeof result.serial, 'number'); |
| 244 | ok(result.serial > 0 && result.serial < 4294967295); |
| 245 | strictEqual(typeof result.refresh, 'number'); |
| 246 | ok(result.refresh > 0 && result.refresh < 2147483647); |
| 247 | strictEqual(typeof result.retry, 'number'); |
| 248 | ok(result.retry > 0 && result.retry < 2147483647); |
| 249 | strictEqual(typeof result.expire, 'number'); |
| 250 | ok(result.expire > 0 && result.expire < 2147483647); |
| 251 | strictEqual(typeof result.minttl, 'number'); |
| 252 | ok(result.minttl >= 0 && result.minttl < 2147483647); |
| 253 | } |
| 254 | |
| 255 | validateResult(await dnsPromises.resolveSoa(addresses.SOA_HOST)); |
| 256 | }, |
| 257 | }; |
| 258 | |
| 259 | // Tests are taken from |
| 260 | // https://github.com/nodejs/node/blob/d7fdbb994cda8b2e1da4240eb97270c6abbaa9dd/test/internet/test-dns.js#L308 |
| 261 | export const resolveNaptr = { |
| 262 | async test() { |
| 263 | function validateResult(result) { |
| 264 | ok(result.length > 0); |
| 265 | |
| 266 | for (const item of result) { |
| 267 | strictEqual(typeof item, 'object'); |
| 268 | strictEqual(typeof item.flags, 'string'); |
| 269 | strictEqual(typeof item.service, 'string'); |
| 270 | strictEqual(typeof item.regexp, 'string'); |
| 271 | strictEqual(typeof item.replacement, 'string'); |
| 272 | strictEqual(typeof item.order, 'number'); |
| 273 | strictEqual(typeof item.preference, 'number'); |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | validateResult(await dnsPromises.resolveNaptr(addresses.NAPTR_HOST)); |
| 278 | }, |
| 279 | }; |
| 280 | |
| 281 | export const resolve4 = { |
| 282 | async test() { |
| 283 | function validateResult(result) { |
| 284 | ok(result.length > 0); |
| 285 | |
| 286 | for (const item of result) { |
| 287 | strictEqual(typeof item, 'string'); |
| 288 | // TODO(soon): Validate IPv4 |
| 289 | // ok(isIPv4(item)); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | validateResult(await dnsPromises.resolve4(addresses.INET4_HOST)); |
| 294 | }, |
| 295 | }; |
| 296 | |
| 297 | // Tests are taken from |
| 298 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/internet/test-dns.js#L86 |
| 299 | export const resolve4TTL = { |
| 300 | async test() { |
| 301 | function validateResult(result) { |
| 302 | ok(result.length > 0); |
| 303 | |
| 304 | for (const item of result) { |
| 305 | strictEqual(typeof item, 'object'); |
| 306 | strictEqual(typeof item.ttl, 'number'); |
| 307 | strictEqual(typeof item.address, 'string'); |
| 308 | ok(item.ttl >= 0); |
| 309 | // TODO(soon): Validate IPv4 |
| 310 | // ok(isIPv4(item.address)); |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | validateResult( |
| 315 | await dnsPromises.resolve4(addresses.INET4_HOST, { |
| 316 | ttl: true, |
| 317 | }) |
| 318 | ); |
| 319 | }, |
| 320 | }; |
| 321 | |
| 322 | export const resolve6 = { |
| 323 | async test() { |
| 324 | function validateResult(result) { |
| 325 | ok(result.length > 0); |
| 326 | |
| 327 | for (const item of result) { |
| 328 | strictEqual(typeof item, 'string'); |
| 329 | // TODO(soon): Validate IPv6 |
| 330 | // ok(isIPv6(item)); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | validateResult(await dnsPromises.resolve6(addresses.INET6_HOST)); |
| 335 | }, |
| 336 | }; |
| 337 | |
| 338 | // Tests are taken from |
| 339 | // https://github.com/nodejs/node/blob/d5d1e80763202ffa73307213211148571deac27c/test/internet/test-dns.js#L114 |
| 340 | export const resolve6TTL = { |
| 341 | async test() { |
| 342 | function validateResult(result) { |
| 343 | ok(result.length > 0); |
| 344 | |
| 345 | for (const item of result) { |
| 346 | strictEqual(typeof item, 'object'); |
| 347 | strictEqual(typeof item.ttl, 'number'); |
| 348 | strictEqual(typeof item.address, 'string'); |
| 349 | ok(item.ttl >= 0); |
| 350 | // TODO(soon): Validate IPv6 |
| 351 | // ok(isIPv6(item.address)); |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | validateResult( |
| 356 | await dnsPromises.resolve6(addresses.INET6_HOST, { |
| 357 | ttl: true, |
| 358 | }) |
| 359 | ); |
| 360 | }, |
| 361 | }; |
| 362 | |
| 363 | export const getServers = { |
| 364 | async test() { |
| 365 | deepStrictEqual(await dnsPromises.getServers(), [ |
| 366 | '1.1.1.1', |
| 367 | '2606:4700:4700::1111', |
| 368 | '1.0.0.1', |
| 369 | '2606:4700:4700::1001', |
| 370 | ]); |
| 371 | }, |
| 372 | }; |
| 373 | |
| 374 | // Regression: dns.lookup() with all:true and family:0 must return family:6 for |
| 375 | // IPv6 addresses (was returning family:4 due to copy-paste bug). |
| 376 | export const lookupAllFamilyZeroIPv6Family = { |
| 377 | async test() { |
| 378 | const results = await dnsPromises.lookup(addresses.INET_HOST, { |
| 379 | all: true, |
| 380 | family: 0, |
| 381 | }); |
| 382 | ok(Array.isArray(results), 'expected array of addresses'); |
| 383 | ok(results.length > 0, 'expected at least one address'); |
| 384 | |
| 385 | for (const entry of results) { |
| 386 | strictEqual(typeof entry.address, 'string'); |
| 387 | ok( |
| 388 | entry.family === 4 || entry.family === 6, |
| 389 | `family must be 4 or 6, got ${entry.family}` |
| 390 | ); |
| 391 | } |
| 392 | |
| 393 | // If any IPv6 addresses are returned, they must have family:6 |
| 394 | const ipv6Entries = results.filter((e) => e.address.includes(':')); |
| 395 | for (const entry of ipv6Entries) { |
| 396 | strictEqual( |
| 397 | entry.family, |
| 398 | 6, |
| 399 | `IPv6 address ${entry.address} should have family:6 but got family:${entry.family}` |
| 400 | ); |
| 401 | } |
| 402 | |
| 403 | // If any IPv4 addresses are returned, they must have family:4 |
| 404 | const ipv4Entries = results.filter((e) => !e.address.includes(':')); |
| 405 | for (const entry of ipv4Entries) { |
| 406 | strictEqual( |
| 407 | entry.family, |
| 408 | 4, |
| 409 | `IPv4 address ${entry.address} should have family:4 but got family:${entry.family}` |
| 410 | ); |
| 411 | } |
| 412 | }, |
| 413 | }; |
| 414 | |
| 415 | // Regression: dns.lookup() with default family (0) and all:false must resolve |
| 416 | // hosts that only have A records (was only querying AAAA, failing for IPv4-only). |
| 417 | export const lookupDefaultFamilyResolvesIPv4 = { |
| 418 | async test() { |
| 419 | // Default options (family:0, all:false) — should return an address |
| 420 | const result = await dnsPromises.lookup(addresses.INET4_HOST); |
| 421 | ok(result != null, 'expected a result'); |
| 422 | strictEqual(typeof result.address, 'string'); |
| 423 | ok(result.address.length > 0, 'expected non-empty address'); |
| 424 | ok( |
| 425 | result.family === 4 || result.family === 6, |
| 426 | `family must be 4 or 6, got ${result.family}` |
| 427 | ); |
| 428 | |
| 429 | // Also verify via callback API |
| 430 | const { promise, resolve, reject } = Promise.withResolvers(); |
| 431 | dns.lookup(addresses.INET4_HOST, (error, address, family) => { |
| 432 | if (error) { |
| 433 | reject(error); |
| 434 | return; |
| 435 | } |
| 436 | strictEqual(typeof address, 'string'); |
| 437 | ok(address.length > 0, 'expected non-empty address from callback'); |
| 438 | ok(family === 4 || family === 6, `family must be 4 or 6, got ${family}`); |
| 439 | resolve(); |
| 440 | }); |
| 441 | await promise; |
| 442 | }, |
| 443 | }; |
| 444 | |
| 445 | // Regression: Resolver.resolvePtr must exist (was misspelled as 'esolvePtr'). |
| 446 | export const resolverResolvePtrExists = { |
| 447 | async test() { |
| 448 | const resolver = new dnsPromises.Resolver(); |
| 449 | strictEqual( |
| 450 | typeof resolver.resolvePtr, |
| 451 | 'function', |
| 452 | 'Resolver.resolvePtr should be a function' |
| 453 | ); |
| 454 | // Actually call it to verify it works end-to-end |
| 455 | const result = await resolver.resolvePtr(addresses.PTR_HOST); |
| 456 | ok(Array.isArray(result), 'expected array result'); |
| 457 | ok(result.length > 0, 'expected at least one PTR record'); |
| 458 | for (const item of result) { |
| 459 | strictEqual(typeof item, 'string'); |
| 460 | } |
| 461 | }, |
| 462 | }; |
| 463 | |
| 464 | // Tests are taken from |
| 465 | // https://github.com/nodejs/node/blob/3153c8333e3a8f2015b795642def4d81ec7cd7b3/test/parallel/test-dns-lookup.js |
| 466 | export const testDnsLookup = { |
| 467 | async test() { |
| 468 | { |
| 469 | const err = { |
| 470 | code: 'ERR_INVALID_ARG_TYPE', |
| 471 | name: 'TypeError', |
| 472 | }; |
| 473 | |
| 474 | throws(() => dns.lookup(1, {}), err); |
| 475 | throws(() => dnsPromises.lookup(1, {}), err); |
| 476 | } |
| 477 | |
| 478 | throws( |
| 479 | () => { |
| 480 | dns.lookup(false, 'cb'); |
| 481 | }, |
| 482 | { |
| 483 | code: 'ERR_INVALID_ARG_TYPE', |
| 484 | name: 'TypeError', |
| 485 | } |
| 486 | ); |
| 487 | |
| 488 | throws( |
| 489 | () => { |
| 490 | dns.lookup(false, 'options', 'cb'); |
| 491 | }, |
| 492 | { |
| 493 | code: 'ERR_INVALID_ARG_TYPE', |
| 494 | name: 'TypeError', |
| 495 | } |
| 496 | ); |
| 497 | |
| 498 | { |
| 499 | const family = 20; |
| 500 | const err = { |
| 501 | code: 'ERR_INVALID_ARG_VALUE', |
| 502 | name: 'TypeError', |
| 503 | message: `The property 'options.family' must be one of: 0, 4, 6. Received ${family}`, |
| 504 | }; |
| 505 | const options = { |
| 506 | family, |
| 507 | all: false, |
| 508 | }; |
| 509 | |
| 510 | throws(() => { |
| 511 | dnsPromises.lookup(false, options); |
| 512 | }, err); |
| 513 | throws(() => { |
| 514 | dns.lookup(false, options, () => {}); |
| 515 | }, err); |
| 516 | } |
| 517 | |
| 518 | [1, 0n, 1n, '', '0', Symbol(), true, false, {}, [], () => {}].forEach( |
| 519 | (family) => { |
| 520 | const err = { code: 'ERR_INVALID_ARG_VALUE' }; |
| 521 | const options = { family }; |
| 522 | throws(() => { |
| 523 | dnsPromises.lookup(false, options); |
| 524 | }, err); |
| 525 | throws(() => { |
| 526 | dns.lookup(false, options, () => {}); |
| 527 | }, err); |
| 528 | } |
| 529 | ); |
| 530 | [0n, 1n, '', '0', Symbol(), true, false].forEach((family) => { |
| 531 | const err = { code: 'ERR_INVALID_ARG_TYPE' }; |
| 532 | throws(() => { |
| 533 | dnsPromises.lookup(false, family); |
| 534 | }, err); |
| 535 | throws(() => { |
| 536 | dns.lookup(false, family, () => {}); |
| 537 | }, err); |
| 538 | }); |
| 539 | |
| 540 | [0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((all) => { |
| 541 | const err = { code: 'ERR_INVALID_ARG_TYPE' }; |
| 542 | const options = { all }; |
| 543 | throws(() => { |
| 544 | dnsPromises.lookup(false, options); |
| 545 | }, err); |
| 546 | throws(() => { |
| 547 | dns.lookup(false, options, () => {}); |
| 548 | }, err); |
| 549 | }); |
| 550 | |
| 551 | [0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((verbatim) => { |
| 552 | const err = { code: 'ERR_INVALID_ARG_TYPE' }; |
| 553 | const options = { verbatim }; |
| 554 | throws(() => { |
| 555 | dnsPromises.lookup(false, options); |
| 556 | }, err); |
| 557 | throws(() => { |
| 558 | dns.lookup(false, options, () => {}); |
| 559 | }, err); |
| 560 | }); |
| 561 | |
| 562 | [0, 1, 0n, 1n, '', '0', Symbol(), {}, [], () => {}].forEach((order) => { |
| 563 | const err = { code: 'ERR_INVALID_ARG_VALUE' }; |
| 564 | const options = { order }; |
| 565 | throws(() => { |
| 566 | dnsPromises.lookup(false, options); |
| 567 | }, err); |
| 568 | throws(() => { |
| 569 | dns.lookup(false, options, () => {}); |
| 570 | }, err); |
| 571 | }); |
| 572 | }, |
| 573 | }; |