Skip to content
File

Blob: src/workerd/api/node/tests/dgram-nodejs-test.js

javascript336 lines
1// Copyright (c) 2025 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
4import * as dgram from 'node:dgram';
5import { strictEqual, deepStrictEqual, throws, ok } from 'node:assert';
6 
7export const dgramTest = {
8 test() {
9 // Note: test was generated by claude with manual tweaks
10 
11 // Test that required exports exist
12 strictEqual(typeof dgram.createSocket, 'function');
13 strictEqual(typeof dgram.Socket, 'function');
14 
15 // Test createSocket with string type - should return Socket instance
16 const socket1 = dgram.createSocket('udp4');
17 ok(socket1 instanceof dgram.Socket);
18 
19 const socket2 = dgram.createSocket('udp6');
20 ok(socket2 instanceof dgram.Socket);
21 
22 // Test createSocket with object type - should return Socket instance
23 const socket3 = dgram.createSocket({ type: 'udp4' });
24 ok(socket3 instanceof dgram.Socket);
25 
26 const socket4 = dgram.createSocket({ type: 'udp6' });
27 ok(socket4 instanceof dgram.Socket);
28 
29 // Test createSocket with callback - should return Socket instance and register callback
30 const callback1 = () => {};
31 const socket5 = dgram.createSocket('udp4', callback1);
32 ok(socket5 instanceof dgram.Socket);
33 
34 const callback2 = () => {};
35 const socket6 = dgram.createSocket({ type: 'udp4' }, callback2);
36 ok(socket6 instanceof dgram.Socket);
37 
38 // Test createSocket argument validation - type must be valid object
39 throws(
40 () => {
41 dgram.createSocket(null);
42 },
43 {
44 code: 'ERR_INVALID_ARG_TYPE',
45 }
46 );
47 
48 throws(
49 () => {
50 dgram.createSocket(123);
51 },
52 {
53 code: 'ERR_INVALID_ARG_TYPE',
54 }
55 );
56 
57 throws(
58 () => {
59 dgram.createSocket([]);
60 },
61 {
62 code: 'ERR_INVALID_ARG_TYPE',
63 }
64 );
65 
66 // Test createSocket callback validation - must be function if provided
67 throws(
68 () => {
69 dgram.createSocket('udp4', 'invalid');
70 },
71 {
72 code: 'ERR_INVALID_ARG_TYPE',
73 }
74 );
75 
76 throws(
77 () => {
78 dgram.createSocket('udp4', 123);
79 },
80 {
81 code: 'ERR_INVALID_ARG_TYPE',
82 }
83 );
84 
85 throws(
86 () => {
87 dgram.createSocket('udp4', {});
88 },
89 {
90 code: 'ERR_INVALID_ARG_TYPE',
91 }
92 );
93 
94 // Test Socket constructor with string type - should return Socket instance
95 const socket7 = new dgram.Socket('udp4');
96 ok(socket7 instanceof dgram.Socket);
97 
98 const socket8 = new dgram.Socket('udp6');
99 ok(socket8 instanceof dgram.Socket);
100 
101 // Test Socket constructor with object type - should return Socket instance
102 const socket9 = new dgram.Socket({ type: 'udp4' });
103 ok(socket9 instanceof dgram.Socket);
104 
105 // Test Socket constructor with callback - should return Socket instance and register callback
106 const callback3 = () => {};
107 const socket10 = new dgram.Socket('udp4', callback3);
108 ok(socket10 instanceof dgram.Socket);
109 
110 // Test Socket constructor argument validation
111 throws(
112 () => {
113 new dgram.Socket(null);
114 },
115 {
116 code: 'ERR_INVALID_ARG_TYPE',
117 }
118 );
119 
120 throws(
121 () => {
122 new dgram.Socket(123);
123 },
124 {
125 code: 'ERR_INVALID_ARG_TYPE',
126 }
127 );
128 
129 throws(
130 () => {
131 new dgram.Socket('udp4', 'invalid');
132 },
133 {
134 code: 'ERR_INVALID_ARG_TYPE',
135 }
136 );
137 
138 // Test Socket prototype methods exist
139 strictEqual(typeof dgram.Socket.prototype.bind, 'function');
140 strictEqual(typeof dgram.Socket.prototype.connect, 'function');
141 strictEqual(typeof dgram.Socket.prototype.disconnect, 'function');
142 strictEqual(typeof dgram.Socket.prototype.send, 'function');
143 strictEqual(typeof dgram.Socket.prototype.sendto, 'function');
144 strictEqual(typeof dgram.Socket.prototype.close, 'function');
145 strictEqual(typeof dgram.Socket.prototype.address, 'function');
146 strictEqual(typeof dgram.Socket.prototype.remoteAddress, 'function');
147 strictEqual(typeof dgram.Socket.prototype.setBroadcast, 'function');
148 strictEqual(typeof dgram.Socket.prototype.setTTL, 'function');
149 strictEqual(typeof dgram.Socket.prototype.setMulticastTTL, 'function');
150 strictEqual(typeof dgram.Socket.prototype.setMulticastLoopback, 'function');
151 strictEqual(
152 typeof dgram.Socket.prototype.setMulticastInterface,
153 'function'
154 );
155 strictEqual(typeof dgram.Socket.prototype.addMembership, 'function');
156 strictEqual(typeof dgram.Socket.prototype.dropMembership, 'function');
157 strictEqual(
158 typeof dgram.Socket.prototype.addSourceSpecificMembership,
159 'function'
160 );
161 strictEqual(
162 typeof dgram.Socket.prototype.dropSourceSpecificMembership,
163 'function'
164 );
165 strictEqual(typeof dgram.Socket.prototype.ref, 'function');
166 strictEqual(typeof dgram.Socket.prototype.unref, 'function');
167 strictEqual(typeof dgram.Socket.prototype.setRecvBufferSize, 'function');
168 strictEqual(typeof dgram.Socket.prototype.setSendBufferSize, 'function');
169 strictEqual(typeof dgram.Socket.prototype.getRecvBufferSize, 'function');
170 strictEqual(typeof dgram.Socket.prototype.getSendBufferSize, 'function');
171 strictEqual(typeof dgram.Socket.prototype.getSendQueueSize, 'function');
172 strictEqual(typeof dgram.Socket.prototype.getSendQueueCount, 'function');
173 
174 // Test methods that are chainable (return this)
175 const testSocket = dgram.createSocket('udp4');
176 
177 const bindResult = testSocket.bind();
178 strictEqual(bindResult, testSocket);
179 
180 const bindResult2 = testSocket.bind(8080);
181 strictEqual(bindResult2, testSocket);
182 
183 const bindResult3 = testSocket.bind(8080, 'localhost');
184 strictEqual(bindResult3, testSocket);
185 
186 // connect is a no-op, should not throw
187 testSocket.connect(8080);
188 testSocket.connect(8080, 'localhost');
189 
190 // disconnect is a no-op, should not throw
191 testSocket.disconnect();
192 
193 // send is a no-op, should not throw
194 testSocket.send(Buffer.from('test'));
195 testSocket.send('test', 8080, 'localhost');
196 
197 // sendto is a no-op, should not throw
198 testSocket.sendto(Buffer.from('test'));
199 
200 // close is chainable, should not throw
201 const closeResult = testSocket.close();
202 strictEqual(closeResult, testSocket);
203 
204 const closeResult2 = testSocket.close(() => {});
205 strictEqual(closeResult2, testSocket);
206 
207 // Test methods that return empty objects
208 const testSocket2 = dgram.createSocket('udp4');
209 
210 const address = testSocket2.address();
211 strictEqual(typeof address, 'object');
212 deepStrictEqual(address, {});
213 
214 const remoteAddress = testSocket2.remoteAddress();
215 strictEqual(typeof remoteAddress, 'object');
216 deepStrictEqual(remoteAddress, {});
217 
218 // Test methods that are no-ops (should not throw)
219 const testSocket3 = dgram.createSocket('udp4');
220 
221 testSocket3.setBroadcast(true);
222 testSocket3.setBroadcast(false);
223 testSocket3.setBroadcast('invalid');
224 
225 testSocket3.setTTL(64);
226 testSocket3.setTTL('invalid');
227 
228 testSocket3.setMulticastTTL(1);
229 testSocket3.setMulticastTTL('invalid');
230 
231 testSocket3.setMulticastLoopback(true);
232 testSocket3.setMulticastLoopback(false);
233 testSocket3.setMulticastLoopback('invalid');
234 
235 testSocket3.setMulticastInterface('127.0.0.1');
236 testSocket3.setMulticastInterface('invalid');
237 
238 testSocket3.addMembership('224.0.0.1');
239 testSocket3.addMembership('224.0.0.1', '127.0.0.1');
240 testSocket3.addMembership('invalid', 'invalid');
241 
242 testSocket3.dropMembership('224.0.0.1');
243 testSocket3.dropMembership('224.0.0.1', '127.0.0.1');
244 testSocket3.dropMembership('invalid', 'invalid');
245 
246 testSocket3.addSourceSpecificMembership('127.0.0.1', '224.0.0.1');
247 testSocket3.addSourceSpecificMembership(
248 '127.0.0.1',
249 '224.0.0.1',
250 '127.0.0.1'
251 );
252 testSocket3.addSourceSpecificMembership('invalid', 'invalid', 'invalid');
253 
254 testSocket3.dropSourceSpecificMembership('127.0.0.1', '224.0.0.1');
255 testSocket3.dropSourceSpecificMembership(
256 '127.0.0.1',
257 '224.0.0.1',
258 '127.0.0.1'
259 );
260 testSocket3.dropSourceSpecificMembership('invalid', 'invalid', 'invalid');
261 
262 testSocket3.setRecvBufferSize(1024);
263 testSocket3.setRecvBufferSize('invalid');
264 
265 testSocket3.setSendBufferSize(1024);
266 testSocket3.setSendBufferSize('invalid');
267 
268 // Test methods that return this
269 const testSocket4 = dgram.createSocket('udp4');
270 
271 const refResult = testSocket4.ref();
272 strictEqual(refResult, testSocket4);
273 
274 const unrefResult = testSocket4.unref();
275 strictEqual(unrefResult, testSocket4);
276 
277 // Test methods that return numbers
278 const testSocket5 = dgram.createSocket('udp4');
279 
280 const recvBufferSize = testSocket5.getRecvBufferSize();
281 strictEqual(recvBufferSize, 0);
282 
283 const sendBufferSize = testSocket5.getSendBufferSize();
284 strictEqual(sendBufferSize, 0);
285 
286 const sendQueueSize = testSocket5.getSendQueueSize();
287 strictEqual(sendQueueSize, 0);
288 
289 const sendQueueCount = testSocket5.getSendQueueCount();
290 strictEqual(sendQueueCount, 0);
291 
292 // Test Symbol.asyncDispose method exists and is a no-op
293 strictEqual(typeof dgram.Socket.prototype[Symbol.asyncDispose], 'function');
294 
295 // Test asyncDispose returns a Promise
296 const testSocket6 = dgram.createSocket('udp4');
297 const disposeResult = testSocket6[Symbol.asyncDispose]();
298 ok(disposeResult instanceof Promise);
299 
300 // Verify the promise resolves to undefined
301 disposeResult.then((result) => {
302 strictEqual(result, undefined);
303 });
304 
305 // Test default export
306 strictEqual(typeof dgram.default, 'object');
307 strictEqual(dgram.default.createSocket, dgram.createSocket);
308 strictEqual(dgram.default.Socket, dgram.Socket);
309 
310 // Test createSocket with more complex options
311 const socket11 = dgram.createSocket({
312 type: 'udp4',
313 reuseAddr: true,
314 ipv6Only: false,
315 recvBufferSize: 1024,
316 sendBufferSize: 1024,
317 });
318 ok(socket11 instanceof dgram.Socket);
319 
320 // Test edge cases with validation
321 throws(
322 () => {
323 dgram.createSocket({ type: 'udp4' }, null);
324 },
325 {
326 code: 'ERR_INVALID_ARG_TYPE',
327 }
328 );
329 
330 // Test that Socket extends EventEmitter properly
331 // Note: We can't test this directly since constructor throws, but we can check prototype chain
332 const EventEmitter = dgram.Socket.prototype.constructor;
333 strictEqual(typeof EventEmitter, 'function');
334 },
335};