• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23const common = require('../common');
24
25// This test asserts the semantics of dgram::socket.bind({ exclusive })
26// when called from a cluster.Worker
27
28const assert = require('assert');
29const cluster = require('cluster');
30const dgram = require('dgram');
31const BYE = 'bye';
32const WORKER2_NAME = 'wrker2';
33
34if (cluster.isPrimary) {
35  const worker1 = cluster.fork();
36
37  if (common.isWindows) {
38    worker1.on('error', common.mustCall((err) => {
39      console.log(err);
40      assert.strictEqual(err.code, 'ENOTSUP');
41      worker1.kill();
42    }));
43    return;
44  }
45
46  worker1.on('message', common.mustCall((msg) => {
47    console.log(msg);
48    assert.strictEqual(msg, 'success');
49
50    const worker2 = cluster.fork({ WORKER2_NAME });
51    worker2.on('message', common.mustCall((msg) => {
52      console.log(msg);
53      assert.strictEqual(msg, 'socket3:EADDRINUSE');
54
55      // finish test
56      worker1.send(BYE);
57      worker2.send(BYE);
58    }));
59    worker2.on('exit', common.mustCall((code, signal) => {
60      assert.strictEqual(signal, null);
61      assert.strictEqual(code, 0);
62    }));
63  }));
64  worker1.on('exit', common.mustCall((code, signal) => {
65    assert.strictEqual(signal, null);
66    assert.strictEqual(code, 0);
67  }));
68  // end primary code
69} else {
70  // worker code
71  process.on('message', common.mustCallAtLeast((msg) => {
72    if (msg === BYE) process.exit(0);
73  }), 1);
74
75  const isSecondWorker = process.env.WORKER2_NAME === WORKER2_NAME;
76  const socket1 = dgram.createSocket('udp4', common.mustNotCall());
77  const socket2 = dgram.createSocket('udp4', common.mustNotCall());
78  const socket3 = dgram.createSocket('udp4', common.mustNotCall());
79
80  socket1.on('error', (err) => assert.fail(err));
81  socket2.on('error', (err) => assert.fail(err));
82
83  // First worker should bind, second should err
84  const socket3OnBind =
85    isSecondWorker ?
86      common.mustNotCall() :
87      common.mustCall(() => {
88        const port3 = socket3.address().port;
89        assert.strictEqual(typeof port3, 'number');
90        process.send('success');
91      });
92  // An error is expected only in the second worker
93  const socket3OnError =
94    !isSecondWorker ?
95      common.mustNotCall() :
96      common.mustCall((err) => {
97        process.send(`socket3:${err.code}`);
98      });
99  const address = common.localhostIPv4;
100  const opt1 = { address, port: 0, exclusive: false };
101  const opt2 = { address, port: common.PORT, exclusive: false };
102  const opt3 = { address, port: common.PORT + 1, exclusive: true };
103  socket1.bind(opt1, common.mustCall(() => {
104    const port1 = socket1.address().port;
105    assert.strictEqual(typeof port1, 'number');
106    socket2.bind(opt2, common.mustCall(() => {
107      const port2 = socket2.address().port;
108      assert.strictEqual(typeof port2, 'number');
109      socket3.on('error', socket3OnError);
110      socket3.bind(opt3, socket3OnBind);
111    }));
112  }));
113}
114