Skip to content

Socket.IO Engine: Dynamic Query Params (e.g., JWT Token) Cannot Be Set via Processor or before Hook #3577

@Techno-manish

Description

@Techno-manish

Description
When using Artillery to test a Socket.IO server, it is not possible to dynamically set query parameters (such as a JWT token) for the connection using a processor function or the before hook. The Socket.IO engine appears to interpolate variables for the connection before any scenario flow or hooks execute, so tokens generated dynamically are not used during the socket handshake.

This makes it impossible to perform authenticated load testing with per-user dynamic tokens.

To Reproduce

  1. Create a processor function that generates a JWT and assigns it to context.vars.token.
  2. Reference {{ token }} in the socketio.query section of the YAML config.
  3. Use a before hook or a function step at the start of the scenario to set the token.
  4. Run the test and observe that the server receives token: undefined (or the literal string {{ token }}), and authentication fails.

Example config:

config:
  target: "http://localhost:3000"
  processor: "./utils/websocket-utils/loadTokenData.js"
  phases:
    - duration: 2
      arrivalRate: 1
  socketio:
    transports: ["websocket"]
    query:
      token: "{{ token }}"
      platformType: "ios"
  variables: {}
  defaults:
    socketio:
      timeout: 60000
      forceNew: true

before:
  flow:
    - function: "setTokenBeforeRequest"

scenarios:
  - name: "Test"
    engine: socketio
    flow:
      - emit:
          channel: "getOnlineUsers"
          data:
            page: 1
            limit: 10

Processor example:

async function setTokenBeforeRequest(context, events, done) {
  context.vars.token = "my_generated_jwt";
  return done();
}
module.exports = { setTokenBeforeRequest };

Expected behavior
The token generated/set in the processor or before hook should be available for interpolation in socketio.query when the connection is established.

Actual behavior
The connection is established before the processor or before hook runs, so token is undefined and authentication fails. The server logs show token: undefined or token: unknown.

Workarounds tried

  • Using static tokens in the variables section (works, but not dynamic)
  • Using before hooks and scenario functions (does not work)
  • Using both artillery and artillery-engine-socketio-v3 engines
  • Upgrading to the latest versions

Environment (please complete the following information):

  • Artillery version: 2.0.23
  • artillery-engine-socketio-v3: 1.2.0
  • Node.js version: 22.16.0
  • OS: Windows 10
    Project dependencies:
{
  "dependencies": {
    "dotenv": "^17.1.0",
    "form-data": "^4.0.3",
    "jsonwebtoken": "^9.0.2",
    "path": "^0.12.7",
    "pg": "^8.16.3",
    "sequelize": "^6.37.7"
  },
  "devDependencies": {
    "artillery": "^2.0.23",
    "artillery-engine-socketio-v3": "^1.2.0"
  }
}

Additional context
This issue makes it impossible to use dynamically generated tokens for each virtual user in Socket.IO scenarios, which is a common requirement for authenticated load testing. The HTTP engine does not have this limitation, as hooks can set variables before requests are sent.

Suggested solution
Allow variables set in processor functions or before hooks to be available for interpolation in socketio.query when the connection is established, or provide a way to establish the connection as a scenario step (as in the connect step of artillery-engine-socketio-v3). Alternatively, document this limitation clearly and suggest workarounds.

Thank you for your work on Artillery!
This feature would be extremely useful for anyone load testing authenticated Socket.IO services.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions