uWebSockets.js/tests/Hammer.js
2019-01-26 14:52:43 +01:00

147 lines
3.8 KiB
JavaScript

/* Welcome to the so called hammer test, or if you want, moron test.
* Here we test hammering the library in all kinds of crazy ways.
* Establish connections, have them perform random operations so to
* randomly explore the entire state space while performing random
* operations to test strange edge cases. */
/* Run with AddressSanitizer enabled for best effect. */
/* We use websockets/ws as client counterpart */
const WebSocket = require('ws');
const uWS = require('../dist/uws.js');
const port = 9001;
let openedClientConnections = 0;
let closedClientConnections = 0;
let listenSocket;
/* 0 to 1-less than max */
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function establishNewConnection() {
const ws = new WebSocket('ws://localhost:' + port);
ws.on('open', () => {
/* Open more connections */
if (++openedClientConnections < 1000) {
establishNewConnection();
} else {
/* Stop listening */
uWS.us_listen_socket_close(listenSocket);
}
console.log('Opened ' + openedClientConnections + ' client connections so far.');
performRandomClientAction(ws);
});
/* It seems you can get messages after close?! */
ws.on('message', (data) => {
performRandomClientAction(ws);
});
ws.on('close', () => {
console.log("client was closed");
//performRandomClientAction(ws);
});
}
/* Perform random websockets/ws action */
function performRandomClientAction(ws) {
/* 0, 1 but never 2 */
switch (getRandomInt(2)) {
case 0: {
ws.close();
break;
}
case 1: {
/* Length should be random from small to huge */
try {
ws.send('a test message');
} catch (e) {
/* Apparently websockets/ws can throw at any moment */
}
break;
}
case 2: {
/* This should correspond to hard us_socket_close */
ws.terminate();
break;
}
}
}
/* Perform random uWebSockets.js action */
function performRandomServerAction(ws) {
/* 0, 1 but never 2 */
switch (getRandomInt(2)) {
case 0: {
ws.close();
break;
}
case 1: {
/* Length should be random from small to huge */
ws.send('a test message', false);
break;
}
case 2: {
/* This should correspond to hard us_socket_close */
ws.terminate();
break;
}
}
}
const app = uWS./*SSL*/App({
key_file_name: 'misc/key.pem',
cert_file_name: 'misc/cert.pem',
passphrase: '1234'
}).ws('/*', {
compression: 0,
maxPayloadLength: 16 * 1024 * 1024,
idleTimeout: 10,
open: (ws, req) => {
/* Doing a terminate here will be interesting */
performRandomServerAction(ws);
},
message: (ws, message, isBinary) => {
performRandomServerAction(ws);
},
drain: (ws) => {
// todo: dont send over a certain backpressure
//performRandomServerAction(ws);
},
close: (ws, code, message) => {
try {
performRandomServerAction(ws);
} catch (e) {
/* We expect to land here always, since socket is invalid */
return;
}
/* We should never land here */
uWS.print('ERROR: Did not throw in close!');
process.exit(-1);
}
}).any('/*', (res, req) => {
res.end('Nothing to see here!');
}).listen(port, (token) => {
if (token) {
console.log('Hammering on port ' + port);
/* Establish first connection */
establishNewConnection();
/* Use this to stop listening when done */
listenSocket = token;
}
});
/* Yes we do this crazy thing here */
process.on('beforeExit', () => {
app.forcefully_free();
});