Files
http-latency-prober/python/configs/usage-simple.md
Jan Novak 16fff2f964 docs: add usage-phases.md beside usage-simple.md in python/configs/
- Rename python/configs/usage.md → usage-simple.md so both scripts have a
  parallel runnable reference file in the same directory
- Add python/configs/usage-phases.md: runnable sh commands + real expected
  output for phases.py against every error-path config, including a note on
  the key difference from simple.py (HTTP 4xx exits 0 in phases.py vs 1 in
  simple.py because phases.py completes at the network level)
- Update doc cross-links in docs/usage/py-simple.md and py-phases.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:11:53 +02:00

5.0 KiB

simple.py — Example Config Files

Each .txt file in this directory targets a distinct error path so you can observe simple.py's behaviour for every failure class. Run them from the python/ directory.


all-ok.txt — all sites respond successfully

python simple.py configs/all-ok.txt
echo "exit: $?"

Expected output:

OK        xxx.xx ms  https://example.com
OK        xxx.xx ms  https://www.google.com
OK        xxx.xx ms  https://www.iana.org
exit: 0

dns-failure.txt — DNS resolution fails

Hostnames use the .invalid TLD (RFC 2606), which is guaranteed never to resolve. Fails in milliseconds.

python simple.py configs/dns-failure.txt
echo "exit: $?"

Expected output:

FAIL   ([Errno 8] nodename nor servname provided, or not known)  https://this-host-does-not-exist.invalid
FAIL   ([Errno 8] nodename nor servname provided, or not known)  http://no.such.host.invalid
exit: 1

connection-refused.txt — TCP connection refused

Loopback addresses with no server listening. The OS rejects the SYN immediately (sub-millisecond failure).

python simple.py configs/connection-refused.txt
echo "exit: $?"

Expected output:

FAIL   ([Errno 61] Connection refused)  http://127.0.0.1:9999
FAIL   ([Errno 61] Connection refused)  http://127.0.0.1:19999
exit: 1

timeout.txt — connect hangs until timeout

Non-routable IPs (private/documentation ranges) silently drop TCP SYNs. simple.py waits the full 10-second timeout per host.

⚠️ This run takes approximately 20 seconds to complete.

python simple.py configs/timeout.txt
echo "exit: $?"

Expected output (after ~20 s):

FAIL   (timed out)  http://10.255.255.1/
FAIL   (timed out)  http://192.0.2.1/
exit: 1

tls-errors.txt — TLS certificate errors

Uses badssl.com endpoints with intentionally broken certificates. Requires internet access; badssl.com must be reachable.

python simple.py configs/tls-errors.txt
echo "exit: $?"

Expected output:

FAIL   ([SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired …)     https://expired.badssl.com/
FAIL   ([SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate …)     https://self-signed.badssl.com/
FAIL   ([SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer …)  https://incomplete-chain.badssl.com/
exit: 1

Note: badssl.com occasionally resets connections mid-handshake. When that happens, the error reads [Errno 54] Connection reset by peer instead of CERTIFICATE_VERIFY_FAILED. The key behaviour is the same — every entry is reported as FAIL and the script exits 1. This demonstrates that simple.py handles both SSL-level and network-level TLS failures uniformly.


http-errors.txt — HTTP 4xx / 5xx status codes

urllib.request.urlopen() raises HTTPError for 4xx/5xx, so simple.py reports these as FAIL even though the server responded. The URLs are real paths that reliably return 404 on stable public servers. Requires internet access.

python simple.py configs/http-errors.txt
echo "exit: $?"

Expected output:

FAIL   (HTTP Error 404: Not Found)  https://www.google.com/this-page-does-not-exist-at-all-1234567890
FAIL   (HTTP Error 404: Not Found)  https://github.com/this-repo-does-not-exist-abcxyz123/no-way
FAIL   (HTTP Error 404: Not Found)  https://www.iana.org/this-page-does-not-exist-either
exit: 1

mixed.txt — one of each (no timeout)

One successful site followed by one entry from each fast error class (DNS, connection-refused, TLS, HTTP). Timeout is excluded so the run completes quickly.

python simple.py configs/mixed.txt
echo "exit: $?"

Expected output:

OK        xxx.xx ms  https://example.com
FAIL   ([Errno 8] nodename nor servname …)        https://no.such.host.invalid
FAIL   ([Errno 61] Connection refused)             http://127.0.0.1:9999
FAIL   ([SSL: CERTIFICATE_VERIFY_FAILED] …)       https://self-signed.badssl.com/
FAIL   (HTTP Error 404: Not Found)                 https://github.com/this-repo-does-not-exist-abcxyz123/no-way
exit: 1

Note: the TLS entry may occasionally show [Errno 54] Connection reset by peer instead of CERTIFICATE_VERIFY_FAILED — badssl.com sometimes drops the connection before the handshake completes. Both are reported as FAIL; run tls-errors.txt in isolation for consistent cert-verification messages.


Run all configs

Iterate over every config file (skip timeout.txt for a quick sweep, or omit the exclusion to run all):

# Quick sweep — skips the slow timeout config
for f in configs/*.txt; do
    [[ "$f" == *timeout* ]] && continue
    echo
    echo "=== $f ==="
    python simple.py "$f"
    echo "exit: $?"
done
# Full sweep — includes timeout (~20 s extra)
for f in configs/*.txt; do
    echo
    echo "=== $f ==="
    python simple.py "$f"
    echo "exit: $?"
done