Skip to content

Releases: Perfscale/perfscale

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 20:11
v0.7.0
4dc63a1
  • gRPC load testing: new std/grpc@v1 action family — grpc (one-shot
    unary), grpc-connect / grpc-call, and grpc-stream-open / -send /
    -recv / -close for client/bidi/server streaming. Calls are dynamic (no
    codegen): the schema comes from a base64 descriptor_set (e.g. fetched over
    HTTP and passed through ${{ fetch.body_base64 }}) or server reflection
    (reflection: true, cached per URL). Payloads are protobuf-JSON with
    ${…} token expansion, expect_status asserts the gRPC status code, and
    the family reports grpc_req_duration, grpc_msg_rtt, grpc_msgs_sent /
    grpc_msgs_received, and grpc_req_failed metrics.
  • std/http@v1 binary responses now return body_base64 (with an empty
    body) when the content type is not textual — previously the body was
    lossy-decoded as UTF-8. Textual responses are unchanged.

Full Changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 11:01
v0.6.0
c801667

Added

  • WebSocket support — six new built-in actions, free and open source like
    every std/* transport. Two styles:

    A one-shot session (std/ws@v1) connects, exchanges messages, and
    closes in one step — timed as a single latency sample:

    steps:
      - uses: std/ws@v1
        with:
          url: wss://stream.example.com/feed
          messages:
            - send: '{"op":"subscribe","channel":"trades","id":"sub-${seq}"}'
              until_json: { type: trade }
        check:
          message_matches: { type: trade }

    A live connection (std/ws-connect@v1 + ws-send / ws-recv /
    ws-ping / ws-close) stays open across steps within an iteration, so WS
    traffic interleaves with HTTP steps:

    steps:
      - uses: std/ws-connect@v1
        with: { url: "wss://stream.example.com/feed" }
        outputs: feed
      - uses: std/ws-send@v1
        with:
          id: "${{ feed.id }}"
          send: '{"op":"order","id":"ord-${seq}","px":${randf(1.05,1.15,5)}}'
          repeat: 100
          interval_ms: 50
      - uses: std/ws-recv@v1
        with: { id: "${{ feed.id }}", until_json: { type: fill } }
      - uses: std/ws-close@v1
        with: { id: "${{ feed.id }}" }

    Text and binary (base64) frames, subprotocols (graphql-ws, STOMP, …),
    wss:// with skipTLSVerify for staging, and connection profiles via
    connection: ${{ config.x }}. See examples/websocket.test.yaml and
    docs/core/actions.md.

  • Dynamic message generator in the open engine: text payloads expand
    single-brace tokens per send — ${seq}, ${uuid}, ${now} / ${now_ms} /
    ${now_iso}, ${rand(a,b)}, ${randf(a,b,dp)}, ${choice(x|y|z)} — and
    repeat + interval_ms emit a stream of unique messages from one template.

  • Message asserts in std/check@v1: message_contains,
    message_matches (JSON-subset), and messages_count_gte work over the
    messages list any protocol action exposes (WebSocket and FIX alike), with
    at-least-one-matches semantics; on: got.messages.0 addresses a single
    message by position.

  • Custom histogram metrics: an action reporting an array of millisecond
    samples under its metrics key gets a full percentile summary line
    (avg/p(50)/p(90)/p(95)/p(99)/min/max count=N). The engine uses it for
    ws_msg_rtt — time from a send to the first reply matching your
    until-condition. Handshakes and one-shot sessions feed http_req_duration;
    waiting on server pushes deliberately does not.

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 16:35
v0.5.0
e2fdc23

Added

  • npm install: npm install -g @perfscale/exe installs the standalone
    binary for your platform (esbuild-style optionalDependencies — npm fetches
    only the matching @perfscale/<os>-<arch> package; Linux builds are static
    musl and run on any distro). Published automatically from every release tag.
  • Actions can emit custom run metrics: a metrics object in a step's output
    value (name → number) is summed across VUs/iterations by the native engine and
    reported in the summary as <name>: <total> <rate>/s — the same line shape the
    downstream parsers already read. Enables protocol-specific dashboards (e.g. FIX
    send/receive message rates) without changing the metrics pipeline.

What's Changed

  • feat(core): periodic [stats] lines from the native runner by @vitalics in #1

New Contributors

Full Changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 10:30
v0.4.0
7844ab3

Added

  • New std/tcp@v1 and std/udp@v1 actions: raw TCP/UDP probes — connect (TCP),
    send an optional payload (send / send_base64), optionally read a response
    and assert a substring (expect), all with per-request timing. Latency feeds
    the same metrics as HTTP, so percentiles are comparable across transports.
  • Config files gain a before: block: setup steps that run once before the
    load (not per iteration). Each step's outputs is exposed to test steps under
    the config namespace — ${{ config.<name>.<field> }} — for building a
    reusable value (e.g. a token or connection profile). A failing setup step
    aborts the run before any VU starts.
  • Config files gain a variables: block: static values exposed to steps as
    ${{ vars.<key> }}.
  • Steps accept uses: as an alias for use:.
  • New std/file-read@v1 action: read a file once into a process-wide cache
    (revalidated by mtime/size) and reference its content from later steps via
    ${{ name.content }}text or base64 encoding.
  • New std/file-write@v1 action: write (or append) content to a file —
    e.g. persist ${{ resp.body }} to disk; base64 content is decoded before
    writing.
  • std/http@v1 output now includes response headers (lowercase names),
    and ${{ ... }} paths descend nested objects — chain requests on response
    headers: headers: { x-session: "${{ r1.headers.x-session }}" }.
  • std/http@v1 can send multipart/form-data: a multipart: array of
    parts — text fields (value) and file uploads (file, with optional
    filename/content_type). Mutually exclusive with body; the boundary
    header is set automatically.

Changed

  • Release notes are now written by hand in UPCOMING.md instead of being a
    bare commit diff; the release workflow publishes and then resets the file.
  • Steps without ${{ ... }} placeholders skip the interpolation pass
    entirely — no per-iteration deep clone of the with: block on the hot
    path. The ${{ ... }} variable syntax is now fully documented in the
    YAML reference.
  • The native engine tracks request durations in a fixed-size HDR histogram
    (~tens of KB) instead of storing every sample: long soak runs no longer
    grow memory 8 bytes per request (a 30-hour run at 10k RPS previously
    needed ~26 GB at the final summary). Quantiles are now within ≤1% of the
    exact value — invisible at the precision the summary prints.
  • The step engine exposes an ActionHandler registration seam
    (register_action) so downstream builds can add custom pro/* actions
    without forking; built-in std/* actions pay no lookup cost for it.

Full Changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 13:01
v0.3.0
74436bb

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 10:53
v0.2.0
c1bb140

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 08:36
v0.1.0
51340df