Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testing

xrat includes a comprehensive testing pipeline that measures connectivity, latency, and throughput for stored proxy configs.

Test Stages

The test command runs up to 5 stages in sequence:

StageMeasuresDefaultImplementation
ICMPPing success and latencyEnabledSpawns system ping command
TCPTCP connect success and latencyEnabledDirect TCP socket connection
Real DelayHTTP round-trip latency through proxyEnabledSpawns proxy, makes HTTP request
DownloadDownload throughput through proxyDisabledDownloads file through proxy
UploadUpload throughput through proxyDisabledPOSTs data through proxy

Stage Configuration

Configure stages in config.toml:

[testing]
concurrency = 0  # 0 = auto-detect
order = ["icmp", "real_delay", "download"]
failure_policy = "continue"

[testing.icmp]
enabled = true
timeout = 3000
attempts = 3

[testing.tcp]
enabled = true
timeout = 5000

[testing.real_delay]
enabled = true
url = "https://www.gstatic.com/generate_204"
timeout = 10_000

[testing.download]
enabled = false
url = "https://cachefly.cachefly.net/50mb.test"
timeout = 30_000

Stage Order

The order array controls ICMP, real-delay, and download ordering. TCP is a gate before real-delay when enabled. Upload is optional and runs after download only when --upload-url is provided.

Example: skip ICMP, run only real-delay and download:

order = ["real_delay", "download"]

Failure Policy

Controls behavior when a stage fails:

PolicyBehavior
continueRun all stages regardless of failures
skip_remainingStop testing this config after first failure
mark_failedMark config as failed, skip remaining stages

ICMP Stage

Measures ICMP ping latency by spawning the system ping command.

Configuration

[testing.icmp]
enabled = true
timeout = 3000   # ms per attempt
attempts = 3     # number of ping packets

Output

  • icmp_ok β€” boolean success
  • icmp_ms β€” average latency in milliseconds
  • icmp_attempts β€” number of packets sent

Implementation

xrat spawns ping -c <attempts> -W <timeout> <address> and parses stdout for packet loss and round-trip times.

TCP Stage

Measures TCP connection latency to the proxy’s address:port.

Configuration

[testing.tcp]
enabled = true
timeout = 5000  # ms

Output

  • tcp_ok β€” boolean success
  • tcp_ms β€” connection time in milliseconds
  • failure_kind β€” failure classification (if failed)

Failure Classification

TCP failures are classified into categories:

CategoryDescription
DNSDNS resolution failed
TimeoutConnection timed out
RefusedConnection refused (port closed)
UnreachableNetwork unreachable
PermissionDeniedPermission denied
TLSTLS handshake failed
AuthAuthentication failed
ProcessProxy process failed to start
ProxyProxy returned an error
UnknownUnclassified failure

Real Delay Stage

Measures actual HTTP round-trip latency through the proxy.

How It Works

  1. Generates a temporary Xray probe config with a local SOCKS inbound
  2. Spawns a short-lived Xray process
  3. Waits for the SOCKS port to become ready
  4. Makes an HTTP request through the proxy to the test URL
  5. Measures connect time, TTFB, and total round-trip time
  6. Terminates the Xray process

Configuration

[testing.real_delay]
enabled = true
url = "https://www.gstatic.com/generate_204"
timeout = 10_000  # ms

Output

  • real_delay_ok β€” boolean success
  • real_delay_ms β€” total round-trip time
  • connect_ms β€” TCP connection time
  • ttfb_ms β€” time to first byte
  • http_status β€” HTTP response status code

Probe Config

The probe config uses a minimal setup:

{
  "log": { "loglevel": "warning" },
  "inbounds": [
    {
      "tag": "probe-in",
      "port": <random>,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": { "udp": false }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "<node-protocol>",
      "settings": { ... },
      "stream_settings": { ... }
    }
  ]
}

Download Stage

Measures download throughput by downloading a file through the proxy.

Configuration

[testing.download]
enabled = false
url = "https://cachefly.cachefly.net/50mb.test"
timeout = 30_000  # ms

Output

  • download_mbps β€” throughput in megabits per second

Implementation

  1. Spawns proxy with the config
  2. Downloads the file through the proxy
  3. Measures bytes transferred and elapsed time
  4. Calculates throughput: (bytes * 8) / (seconds * 1_000_000)

Upload Stage

Measures upload throughput by POSTing data through the proxy.

Invocation

xrat test 42 --upload-url https://example.com/upload --upload-timeout 30000

Output

  • upload_mbps β€” throughput in megabits per second

Bulk Testing

Test multiple configs concurrently:

xrat test --enabled-only --concurrency 4

Concurrency

  • 0 = auto-detect based on CPU cores
  • Positive values set exact worker count

Progress Bar

Bulk tests display an animated progress bar (unless --no-progress is used):

Testing configs ━━━━━━━━━━━━━━━━━━━━ 45/150 30% 2m 15s

Output Formats

FormatDescription
tsvTab-separated values (default, terminal-friendly)
csvComma-separated values (spreadsheet-friendly)
jsonJSON array with full details

Sorting

Sort results by:

FieldDescription
statusAlive first, then by failure reason
icmpLowest ICMP latency
real-delayLowest real-delay latency
download-speedHighest download throughput
protocolProtocol name alphabetically
addressServer address alphabetically

Ping Loop

Continuous monitoring mode for a single config:

xrat test 42 --ping --ping-interval 2000

Runs the test repeatedly until Ctrl+C, printing a live summary:

Ping loop for config 42 (vless://example.com:443)
─────────────────────────────────────────────────────
#1  ICMP: 15ms  TCP: 12ms  Real Delay: 145ms  βœ“
#2  ICMP: 14ms  TCP: 11ms  Real Delay: 142ms  βœ“
#3  ICMP: -     TCP: -     Real Delay: -      βœ— timeout
#4  ICMP: 16ms  TCP: 13ms  Real Delay: 148ms  βœ“

GeoIP Enrichment

Optionally enrich test results with GeoIP data (country, city, ASN) using configurable lookup backends.

Backend Types

BackendDescription
mmdbLocal GeoLite2 MMDB files (default)
ipwhoisRemote ipwhois.app API
ip-apiRemote ip-api.com API
chainLocal MMDB with remote fallback

Configuration

[testing.geoip]
enabled = true
backend = "mmdb"             # mmdb | ipwhois | ip-api | chain

mmdb backend

Paths for local GeoLite2 MMDB files. Relative paths are resolved from the config file location, or from XRAT_PATH when set.

[testing.geoip]
country_path = "mmdb/GeoLite2-Country.mmdb"
city_path = "mmdb/GeoLite2-City.mmdb"
asn_path = "mmdb/GeoLite2-ASN.mmdb"

Download MMDB files with the geoip download command.

Remote backends (ipwhois / ip-api)

[testing.geoip.remote]
provider = "ipwhois"         # ipwhois | ip-api
endpoint = ""                # override API endpoint (empty = provider default)
timeout_ms = 5000
api_key = ""                 # provider-specific (if required)
rate_limit_per_minute = 30

Chain backend

Primary is local MMDB; falls back to a remote service on cache/miss or MMDB absence.

[testing.geoip]
backend = "chain"
fallback = "ipwhois"         # ipwhois | ip-api

Caching

Remote lookups are cached in memory to reduce API calls:

[testing.geoip.cache]
enabled = true
ttl_secs = 86400             # per-entry TTL
max_entries = 10000

Test Result Enrichment

When GeoIP enrichment is enabled, test results include:

  • endpoint_ip β€” resolved IP address
  • endpoint_country β€” ISO country code (e.g. NL)
  • endpoint_location β€” location label such as city/country when available
  • endpoint_asn β€” Autonomous System Number and organization (e.g. AS15169 Google LLC)

Test Runs

Tests are grouped into runs for historical analysis:

TablePurpose
connection_test_runsGroups test results (id, kind, created_at)
connection_testsIndividual test results linked to a run

View the latest run summary:

xrat test --latest-run-summary

Filter by country or ASN:

xrat test --latest-run-summary --country US --asn cloudflare

Persistence

All test results are persisted to the database:

FieldDescription
config_idForeign key to configs table
run_idForeign key to connection_test_runs
icmp_ok, icmp_msICMP results
tcp_ok, tcp_msTCP results
real_delay_ok, real_delay_msReal delay results
connect_ms, ttfb_ms, http_statusHTTP details
download_mbps, upload_mbpsThroughput
failure_kind, failure_reasonFailure details
endpoint_ip, endpoint_country, endpoint_asnGeoIP
tested_atTimestamp