Testing Socket.io

Socket.io is a popular library for building real-time event-based applications. Artillery has first-class support for load testing Socket.io. Set the engine attribute of a scenario definition to socketio to enable the Socket.io engine.

Socket.io-specific configuration

Query

Query parameters can be specified as a string or as a dictionary:

config:
  target: "https://myapp.staging:3002"
  socketio:
    query: "user_id=0xc0ffee&color=blue"

or:

config:
  target: "https://myapp.staging:3002"
  socketio:
    query:
      user_id: "0xc0fee"
      color: "blue"

Path

A custom path may be set.

In this example the virtual users will connect to the admin namespace with the custom path mypath.

config:
  target: "https://myapp.staging:3002/admin"
  socketio:
    path: "/mypath"

Extra headers

Extra headers may be passed with extraHeaders option:

config:
  target: "https://myapp.staging:3002/admin"
  socketio:
    extraHeaders:
      x-client-id: abc

Note: This only works if the default polling transport is used. When other transports are used, extra headers won't be taken into account by the server.

Transports

You can skip long-polling and specify that a websocket transport be used straightaway:

config:
  target: "https://myapp.staging:3002/admin"
  socketio:
    transports: ["websocket"]

Socket.io Actions

The Socket.io engine allows for HTTP actions actions to be used in scenarios alongside emit, which is the main Socket.io action. Looping with loop and pausing execution with think is also supported, see HTTP reference for details.

emit

Sending Data

The emit action supports the following basic attributes:

  1. channel - the name of the Socket.io channel to emit to
  2. data - the data to emit (as a string). Note that multiple arguments for emit are not supported yet.
  3. namespace - optional namespace to use for this emit

Acknowledgements & Response Validation

Additionally, if you need to wait for an Socket.io acknowledgement response, or validate a response, the following attributes may also be used:

  1. response - optional object if you want to wait for a response:
    • channel - the name of the channel where the response is received.
    • data - the data to verify is in the response
  2. acknowledge - optional object if you want to wait for an acknowledgement

Notes:

Example

scenarios:
  - engine: "socketio"
    flow:
      # Emit a message and validate the acknowledgement.
      # We expect the second data argument to be an object,
      # with an "answer" attribute which equals 42:
      - emit:
          channel: "echo"
          data: "ping"
          acknowledge:
            match:
              json: "$.1.answer"
              value: 42
      # Emit a message, and validate the response coming back:
      - emit:
          channel: "echo"
          data: "world"
          response:
            channel: "echoed"
            data: "world"
      - think: 1
      # Emit a message and proceed onto the next step:
      - emit:
          channel: "echo"
          data: "do not care about the response"
      - emit:
          channel: "echo"
          data: "still do not care about the response"
      - think: 1
      - emit:
          channel: "echo"
          data: "emit data to namespace /nsp1"
          namespace: "/nsp1"
      - emit:
          channel: "echo"
          data: "emit data to namespace /nsp2"
          namespace: "/nsp2"
      - think: 1
      - emit:
          channel: "echo"
          data: "hello"
          namespace: "/nsp1"
          response:
            channel: "echoed"
            data: "hello in /nsp1"

Mixing in HTTP Actions

HTTP and Socket.io actions can be combined in the same scenario (a common scenario when testing servers based on Express.js):

  config:
    target: "http://127.0.0.1:9092"
    phases:
      - duration: 10
        arrivalRate: 1
  scenarios:
    - engine: "socketio"
      flow:
        - get:
            url: "/test"
        - emit:
            channel: "echo"
            data: "hello"
            response:
              channel: "echoed"
              data: "hello"
        - emit:
            channel: "echo"
            data: "world"
            response:
              channel: "echoed"
              data: "world"
        - think: 1
        - emit:
            channel: "echo"
            data: "do not care about the response"
        - emit:
            channel: "echo"
            data: "still do not care about the response"
        - think: 1

Connecting Without Sending Any Data

You can use think to emulate clients connecting to the app and listening without sending anything themselves.

config:
  target: "http://127.0.0.1:9092"
  phases:
    - duration: 3600
      arrivalRate: 5
scenarios:
  - engine: "socketio"
    flow:
      - think: 600 # do nothing for 10m and disconnect