• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2'use strict';
3const common = require('../common');
4const assert = require('assert');
5const dgram = require('dgram');
6const dns = require('dns');
7const { kStateSymbol } = require('internal/dgram');
8
9// Monkey patch dns.lookup() so that it always fails.
10dns.lookup = function(address, family, callback) {
11  process.nextTick(() => { callback(new Error('fake DNS')); });
12};
13
14const socket = dgram.createSocket('udp4');
15let dnsFailures = 0;
16let sendFailures = 0;
17
18process.on('exit', () => {
19  assert.strictEqual(dnsFailures, 3);
20  assert.strictEqual(sendFailures, 3);
21});
22
23socket.on('error', (err) => {
24  if (/^Error: fake DNS$/.test(err)) {
25    // The DNS lookup should fail since it is monkey patched. At that point in
26    // time, the send queue should be populated with the send() operation. There
27    // should also be two listeners - this function and the dgram internal one
28    // time error handler.
29    dnsFailures++;
30    assert(Array.isArray(socket[kStateSymbol].queue));
31    assert.strictEqual(socket[kStateSymbol].queue.length, 1);
32    assert.strictEqual(socket.listenerCount('error'), 2);
33    return;
34  }
35
36  if (err.code === 'ERR_SOCKET_CANNOT_SEND') {
37    // On error, the queue should be destroyed and this function should be
38    // the only listener.
39    sendFailures++;
40    assert.strictEqual(socket[kStateSymbol].queue, undefined);
41    assert.strictEqual(socket.listenerCount('error'), 1);
42    return;
43  }
44
45  assert.fail(`Unexpected error: ${err}`);
46});
47
48// Initiate a few send() operations, which will fail.
49socket.send('foobar', common.PORT, 'localhost');
50
51process.nextTick(() => {
52  socket.send('foobar', common.PORT, 'localhost');
53});
54
55setImmediate(() => {
56  socket.send('foobar', common.PORT, 'localhost');
57});
58