Skip to content

Troubleshooting ​

Quick checklist for unexpected failures.

Fast triage ​

  1. Run grpctestify check <file> to validate syntax/sections.
  2. Run the same file with --verbose.
  3. Reduce concurrency (--parallel 1) if failures are flaky.
  4. Check endpoint address/TLS settings.

Connection problems ​

Service unavailable ​

  • Verify server is running
  • Confirm ADDRESS value or GRPCTESTIFY_ADDRESS
  • Check TLS settings if server requires TLS/mTLS

Timeout errors ​

Use a higher timeout:

bash
grpctestify test.gctf --timeout 60

For unstable endpoints, run with reduced parallelism to isolate load-related failures:

bash
grpctestify tests/ --parallel 1 --verbose

If behavior is unexpected because of merged runtime settings, inspect effective values:

bash
grpctestify inspect test.gctf --format json
grpctestify explain test.gctf

If behavior differs between run and bench, check the precedence model — they resolve settings in opposite directions:

  • run: section attributes > OPTIONS > CLI runtime baseline/defaults
  • bench: CLI bench flags > BENCH section > bench defaults

Test file problems ​

JSON parse errors ​

  • Validate JSON in REQUEST / RESPONSE / ERROR
  • Remove trailing commas
  • Ensure section markers are valid

Missing required sections ​

  • ENDPOINT is required
  • At least one verification block is required: RESPONSE, ERROR, or ASSERTS
  • RESPONSE and ERROR cannot appear in the same file
  • META (if present) must be the first section and appear only once

Unexpected section behavior ​

  • Use REQUEST_HEADERS instead of legacy HEADERS
  • Keep section markers exact: --- SECTION_NAME ---
  • For inline options, use key=value when needed, or short boolean flags like with_asserts

Assertion problems ​

Expression fails ​

  • Start with simple checks (.status == "ok")
  • Validate paths exist in actual response
  • For metadata checks use @header() / @trailer()

Type/format checks fail ​

  • Verify values match expected format for @timestamp, @url, @ip, @email, @uuid
  • Check raw response types with inspect output before writing strict assertions

Ordering operators fail (.price >= 0) ​

Add a :type annotation when the schema is unknown:

php
.price:number >= 0
.name:string contains "hello"

Or extract the value with a type annotation:

php
price:number = .price
$price >= 0

Debugging commands ​

bash
# Verbose run
grpctestify test.gctf --verbose

# Execution preview
grpctestify test.gctf --dry-run --verbose

# Syntax check
grpctestify check test.gctf

# Inspect parsed structure
grpctestify inspect test.gctf --format json

# Explain execution plan and assertion scopes
grpctestify explain test.gctf

Log levels ​

grpctestify uses standard levels (from quietest to loudest): error, warn, info, debug, trace. Default is warn — only real problems are printed.

  • --verbose / -v raises visibility to info (progress detail, still no gRPC/internal noise).

  • For a bug report, or when something behaves unexpectedly and you want the full picture (dial attempts, TLS/channel setup, descriptor/reflection resolution, retries, per-assertion pass/fail, variable extraction/interpolation, plugin loading, bench data sources), set:

    bash
    RUST_LOG=trace grpctestify run tests/ 2> debug.log

    RUST_LOG=debug is the same idea, one notch quieter (skips the most chatty per-assertion/wire-level trace lines). Both cover every internal crate in one shot — no need to name individual modules.

  • Logs always go to stderr, never stdout — commands like gen that print their real output (a generated .gctf) to stdout for piping stay clean regardless of verbosity, so redirecting stdout to a file is always safe even with RUST_LOG=trace on.

  • RUST_LOG=grpctestify=debug (crate-scoped) only covers the top-level CLI's own logs, not the apif-* library crates underneath — prefer the bare RUST_LOG=debug/=trace form above unless you specifically want to exclude them.

Rhai plugin/reporter scripts (@custom.rhai assertions, .rhai reporters) have their own leveled logging via log_debug()/log_info()/log_warn()/ log_error() — these route through the same mechanism above (respecting --verbose/RUST_LOG), unlike Rhai's raw print()/debug() which always write straight to stdout/stderr regardless of level. See Script Stdlib for the full list.

Environment variables ​

  • GRPCTESTIFY_ADDRESS
  • GRPCTESTIFY_COMPRESSION
  • GRPCTESTIFY_TLS_CA_FILE
  • GRPCTESTIFY_TLS_CERT_FILE
  • GRPCTESTIFY_TLS_KEY_FILE
  • GRPCTESTIFY_TLS_SERVER_NAME

FAQ ​

How do I run a quick smoke test? ​

bash
grpctestify call myservice.test.gctf

How do I see what a test will do without running it? ​

bash
grpctestify explain test.gctf

What is a .gctf file? ​

A gRPC Test File. It defines endpoint, request, expected response, and assertions in a plain text format. See Test Files.

Why does grpctestify check fail on my file? ​

Run grpctestify check --verbose for detailed diagnostics. Common issues: missing required sections, JSON syntax errors, or incorrect assertion expressions.

Can I test streaming endpoints? ​

Yes — unary, server streaming, client streaming, and bidirectional. The streaming mode comes from the method's proto definition; in the test file you just write multiple REQUEST sections (client streaming) or multiple RESPONSE sections (server streaming). See Streaming.

How do benchmark sources work? ​

Define one or more sources in the BENCH section. Each source is a CSV/TSV/NDJSON file with an optional indexed_by column. During bench execution, rows from the primary source drive gRPC requests via template variables. See Data Sources.

Released under the MIT License.