Skip to content

Instantly share code, notes, and snippets.

@d6y
Created March 12, 2025 10:46
Show Gist options
  • Save d6y/66d4d32a8b1627d6e17070f7feb5b0b8 to your computer and use it in GitHub Desktop.
Save d6y/66d4d32a8b1627d6e17070f7feb5b0b8 to your computer and use it in GitHub Desktop.
Example (incomplete) web socket testing with k6
import http from 'k6/http';
import ws from 'k6/ws';
import { check, fail, sleep } from 'k6';
// App specific settings, whatever your app needs
let app = {
apiBase: "http://localhost:8080",
ws1: "ws://localhost:8080/api/foo/subscribe",
ws2: "ws://localhost:8080/api/baz/",
sessionCookieName: "sessionToken",
userPassword: __ENV.USER_PASSWORD,
viewSeconds: 10, // how long is a user on the page for?
};
export let options = {
stages: [
{ duration: "1m", target: 60 }, // Stage 1 lasts 1 minute and builds up to 60 users
{ duration: "2m", target: 600 }, // Build up to 600 users
{ duration: "10m", target: 600 }, // Soak test for 10 minutes
{ duration: "2m", target: 0 }, // Ramp down
],
thresholds: {
http_req_failed: ['rate<0.01'], // http errors should be less than 1%
http_req_duration: ['p(95)<200'], // 95% of requests should be below 200ms
},
};
// Pre-flight custom validation
export function setup() {
if (!app.userPassword) {
fail("Password for login not set. Run with -e USER_PASSWORD=??? to set the password");
}
}
export default function() {
// __VU is a "virtual user ID" provided by k6
const username = `user${__VU}`;
// This example is grabbing a cookie post-login for authentication:
const loginResponse = login(username, app.userPassword);
const cookies = loginResponse.cookies;
const sessionCookie = cookies[app.sessionCookieName];
if (!sessionCookie) {
console.error("No session cookie", username, loginResponse);
fail("Session cookie not found");
}
if (sessionCookie.length !== 1) {
fail("Expected single cookie value");
}
// We will connect to both WS endpoints, then disconnect at the end ("leave the page")
// We're using a cookie-based authentication scheme
// The options are limited:
// https://ably.com/blog/websocket-authentication
const wsParams = {
headers: {
"Cookie": `${sessionCookie[0].name}=${sessionCookie[0].value}`
}
};
// Connect to two web sockets and sit on them for a bit
const ws1Response = connect(app.ws1, wsParams, function(ws1Socket) {
const ws2Response = connect(app.ws2, wsParams, function(ws2Socket) {
sleep(app.viewSeconds);
ws1Socket ? ws1Socket.close() : fail("ws1 failed");
ws2Socket ? ws2Socket.close() : fail("ws2 failed");
});
check(ws2Response, { '101 ws2 status': (res) => res.status === 101 });
});
check(ws1Response, { '101 ws1 status': (res) => res.status === 101 });
}
function login(_username, _password) {
// Exactly how you login is for you to fill in
// Here we're making a post with some form data and headers
return http.post(url, formData, { redirects: 0, headers: headers });
}
function connect(wsUrl, wsParams, fn) {
return ws.connect(wsUrl, wsParams, function(socket) {
socket.on("open", function() {
fn(socket)
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment