Skip to content

Gurl-cli v3.0.0

Choose a tag to compare

@Votline Votline released this 11 Apr 06:47
· 13 commits to main since this release

Release v3.0.0: WebSockets, Default Variables & Precision Control

This update pushes gurl-cli further into the realm of total workflow orchestration. I've introduced native WebSocket support for real-time testing, upgraded our macro syntax to support default fallbacks, and squeezed even more allocations out of the hot path.

🚀 What's New

1. Native WebSocket Support (while:ws://)

You can now test real-time connections directly from your .gurlf configs!

  • Single Fire: Use a standard ws:// URL to establish a connection, send a configured payload, and receive a response.
  • Interactive Mode: Prefix your URL with while:ws:// to halt config processing and open an interactive terminal session, streaming messages natively via os.Stdin. Responses are pretty-printed right in the console.

2. Advanced State Management (Variables vs Envs)

The engine now distinguishes between temporary session data and persistent state:

  • SetVariables & {VARIABLE}: Scoped, in-memory storage. Perfect for passing "props" into import configs without affecting the global environment.
  • SetEnvironments & {ENVIRONMENT}: Manage state across files or OS sessions.
    • from=os: Lives only during the process execution (auto-cleared by OS on exit).
    • from=[filePath]: Persistent disk-backed state. Survives between different gurl-cli calls—essential for multi-step shell pipelines.
  • No failing pipelines because an environment variable was missing. {VARIABLE} and {ENVIRONMENT} macros now support fallback defaults using ; as a separator.
    • Note: Semicolons can be escaped if needed inside your payloads.

Examples: {VARIABLE key=usersproto ; default=../protos/users.proto}, {ENVIRONMENT key=DB_HOST ; from=.env ; default=127.0.0.1}

3. Logic Flow & Branching (Expect)

Build resilient test suites with conditional execution:

  • Status Validation: Define Expect: 200 (HTTP) or Expect: 0 (gRPC OK).
  • Failure Actions: Use fail=crash to stop immediately or fail=[ID] to jump to a specific configuration block (fallback logic) upon failure. After jump gurl-cli also stop immediately.
  • Execution Delays: Precision Wait support, now including milliseconds.

Examples: 'Expect: 200;fail=crash', 'Expect: 200;fail=2', 'Wait:500ms'

4. CLI Evolution: Commands over Flags

Ditched the standard flag package for a more intuitive command-based interface:

  • gurl-cli run [file/raw] — Run a file or a raw Gurlf string directly.
  • gurl-cli create [file] [type] — Generate templates.
  • Raw Execution: If the provided path doesn't exist, the CLI attempts to parse the argument as a raw .gurlf config string. No response file is created after processing.

5. Precision Flow Control

  • Context Deadlines (Timeout): You can now manually set a context timeout (e.g., Timeout: 10s) for any request. This field is inherited dynamically by repeat configs, ensuring your CI pipelines never hang indefinitely on dead servers.
  • TLS Ignoring (IgnoreCert): Added the IgnoreCert field to bypass SSL/TLS verification. This does not persist between configurations. If the previous request had this, but the current one did not, there will be no ignoring.

6. Recursive Configuration (Import)

Keep your test suites DRY. The new import type allows you to nest .gurlf files. Combined with SetVariables, you can create reusable templates that accept dynamic parameters from the parent caller.

7. Smart Randomization

  • New {RANDOM} instruction: Supports oneof=uuid, int(min,max), int, and custom word lists: oneof=str1,str2,...

🏗 Performance & Fixes

I'm continue to optimize the hot path. This release removes external dependencies to minimize binary footprint and GC pressure:

  • Zero-Alloc Response Parsing: Rewrote ParseResponse to use manual byte-scanning instead of dynamic slice creation. Allocations during response injections have been drastically reduced.
  • Allocation-Free Iterators: Standard bytes.Split and json overhead was replaced with custom, manual byte-slice scanning, saving 3+ allocations per config block.
  • Import Config Memory Leak: Fixed a critical bug where long chains of import configs caused RingBuffer overflows and deadlocks because the config objects weren't being released back to the pool properly.
  • Custom UUID Engine: Replaced google/uuid with a zero-allocation fastUUID generator (~48 ns/op).
  • gRPC Safety: Fixed a panic caused by unmarshalling gRPC responses into nil slices when the Data field was empty.

⚡ Benchmarks (v3.0.0)

Tested on AMD Ryzen 7 5800U (linux/amd64).

Component / Function Time (ns/op) Allocations Notes
ParseStream ~362 ns/op 0 allocs/op Full multi-line streaming.
HandleType ~274 ns/op 0 allocs/op unsafe casting + mapping.
fastUUID ~48 ns/op 0 allocs/op 18x faster than standard libs.
fastExtract ~12.6 ns/op 0 allocs/op Rapid field extraction.

⚠️ Breaking Changes

  • Flags Removed: Commands like --config are replaced by positional arguments (run, create).
  • Field Rename: Target_ID is now TargetID for consistency.

📦 Getting Started

go install https://github.com/Votline/Gurl-cli@latest

Or download from github Releases

Try out the new interactive WebSockets

Gurl-cli run "
[ws_chat]
URL:while:ws://localhost:8080/ws
Type:http
[\ws_chat]"

# Run a sequence
Gurl-cli run integration_test.gurlf

# Run a raw config
Gurl-cli run '
[http_config]
URL:http://localhost:8080
Type:http
[\http_config]'