blob: 9f7e23ba0bdaf56779f9acf9e96923ad5d84a4bd [file] [log] [blame]
James M Snell98e54b02017-01-03 21:16:481// 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
Roman Reissf29762f2015-05-19 11:00:0622'use strict';
Fikret Burak Gazioglu0bfd1032016-09-17 08:33:1223const common = require('../common');
Refael Ackermannc9d45c42017-05-18 22:58:0024
25// This test asserts the semantics of dgram::socket.bind({ exclusive })
26// when called from a cluster.Worker
27
Fikret Burak Gazioglu0bfd1032016-09-17 08:33:1228const assert = require('assert');
29const cluster = require('cluster');
30const dgram = require('dgram');
Refael Ackermannc9d45c42017-05-18 22:58:0031const BYE = 'bye';
32const WORKER2_NAME = 'wrker2';
cjihrig029cfc12014-08-22 20:51:5333
cjihrig029cfc12014-08-22 20:51:5334if (cluster.isMaster) {
Fikret Burak Gazioglu0bfd1032016-09-17 08:33:1235 const worker1 = cluster.fork();
cjihrig029cfc12014-08-22 20:51:5336
Rich Trott8e9089a2015-06-23 05:17:5237 if (common.isWindows) {
Refael Ackermannc9d45c42017-05-18 22:58:0038 worker1.on('error', common.mustCall((err) => {
39 console.log(err);
40 assert.strictEqual(err.code, 'ENOTSUP');
Rich Trott8e9089a2015-06-23 05:17:5241 worker1.kill();
Refael Ackermannc9d45c42017-05-18 22:58:0042 }));
Rich Trott8e9089a2015-06-23 05:17:5243 return;
44 }
45
Refael Ackermannc9d45c42017-05-18 22:58:0046 worker1.on('message', common.mustCall((msg) => {
47 console.log(msg);
Fikret Burak Gazioglu0bfd1032016-09-17 08:33:1248 assert.strictEqual(msg, 'success');
cjihrig029cfc12014-08-22 20:51:5349
Refael Ackermannc9d45c42017-05-18 22:58:0050 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 master code
cjihrig029cfc12014-08-22 20:51:5369} else {
Refael Ackermannc9d45c42017-05-18 22:58:0070 // worker code
71 process.on('message', common.mustCallAtLeast((msg) => {
72 if (msg === BYE) process.exit(0);
73 }), 1);
cjihrig029cfc12014-08-22 20:51:5374
Refael Ackermannc9d45c42017-05-18 22:58:0075 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());
cjihrig029cfc12014-08-22 20:51:5379
Refael Ackermannc9d45c42017-05-18 22:58:0080 socket1.on('error', (err) => assert.fail(err));
81 socket2.on('error', (err) => assert.fail(err));
cjihrig029cfc12014-08-22 20:51:5382
Refael Ackermannc9d45c42017-05-18 22:58:0083 // First worker should bind, second should err
84 const socket3OnBind =
85 isSecondWorker ?
Rich Trottaa6fac62017-07-25 17:37:0886 common.mustNotCall() :
87 common.mustCall(() => {
88 const port3 = socket3.address().port;
89 assert.strictEqual(typeof port3, 'number');
90 process.send('success');
91 });
Refael Ackermannc9d45c42017-05-18 22:58:0092 // an error is expected only in the second worker
93 const socket3OnError =
94 !isSecondWorker ?
Rich Trottaa6fac62017-07-25 17:37:0895 common.mustNotCall() :
96 common.mustCall((err) => {
97 process.send(`socket3:${err.code}`);
98 });
Refael Ackermannc9d45c42017-05-18 22:58:0099 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 }));
cjihrig029cfc12014-08-22 20:51:53113}