You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b9a4f00
Browse filesBrowse the repository at this point in the historyBrowse files
docs: record the proxy tier and the httpRequestTimeout unit defect
The suite's README gains what a reader needs about the proxy package: where
the binary comes from, the two environment variables that change how it is
obtained, and the shape of a client built against a session. The translation
skill gains what a writer needs — the harness table, a worked example and the
traps the derivation hit, among them that a parent package's pytest timeout
marker wins over a subpackage's unless the subpackage prepends its own, and
that pytest-asyncio runs a session-scoped async fixture on a different event
loop from the tests.
deviations.md carries the one gated test and its measurement. The unit
mismatch on http_request_timeout was already recorded twice, as something
readable only off the options object; the proxy measures it reaching the wire,
so both rows are corrected and the defect is counted once, as a root cause,
where the gated test is. Its blast radius is bounded by the defaults coming out
right by coincidence — 4 and 10 seconds being TO3l3's and TO3l4's 4000 and
10000 milliseconds — so only a client that configures the option is affected.
Issue #709 is already filed against the same line for a different defect and
the two are cross-referenced, since both change what one attempt may spend of
the RSC15 retry budget.
The counts are recomputed throughout: 1059 Test IDs, 1068 derived tests, 1139
pytest cases, and 67 gated root causes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
history =await wall_clock_poll_until(one_message, description='the message to reach history')
334
338
```
335
339
340
+
## The proxy tier
341
+
342
+
`uts/rest/integration/proxy/<name>.md` becomes
343
+
`test/uts/rest/integration/proxy/<name>_test.py`, and routes its traffic through
344
+
[ably/uts-proxy](https://github.com/ably/uts-proxy) on the way to the sandbox. The
345
+
proxy binds a port per session, takes plain HTTP on it, speaks TLS onwards, applies the
346
+
session's rules and records what crosses it. `uts/docs/proxy.md` governs the tier and
347
+
is worth reading in full before deriving one of these; fetch it the same way as the
348
+
other governing docs.
349
+
350
+
What differs from the rest of the integration tier:
351
+
352
+
-**The client points at the session, not at the sandbox.**`endpoint='localhost'`,
353
+
`port=session.proxy_port`, `tls=False`, `use_binary_protocol=False`. `endpoint` and
354
+
`port` set the primary host, and `fallback_hosts=['localhost']` sets the fallback to
355
+
the same session, so both attempts land in one event log. Leave `fallback_hosts` out
356
+
where the spec does: `endpoint='localhost'` disables fallbacks by itself (REC2c2).
357
+
-**Authentication is a callback.** A plain connection cannot carry basic auth, so
358
+
every client takes `auth_callback=`; see the traps below.
359
+
-**A fault is a rule, and everything else passes through.**`times: 1` faults the
360
+
first request that matches and lets the retry reach the sandbox, which is the shape
361
+
every fallback scenario wants.
362
+
-**The proxy is the second witness.** The SDK's own result answers half the question
363
+
and `session.get_log()` the other half — how many requests were made, in what order,
364
+
and what the proxy answered them with.
365
+
-**The per-test timeout is 300 seconds**, set by the package's own `conftest.py`.
366
+
367
+
| Name | Is |
368
+
|---|---|
369
+
|`proxy_session` fixture, in `rest/integration/proxy/conftest.py`| a specification's `create_proxy_session(...)`, together with its `AFTER EACH TEST: session.close()`. `session = await proxy_session(rules=[...])`, as many times as a test needs, and every session is closed afterwards |
370
+
|`proxy_control` fixture | the running control API, session-scoped. `proxy_session` asks for it, so a test does not have to |
371
+
|`create_proxy_session(endpoint=SANDBOX_ENDPOINT, port=None, rules=None, timeout_ms=SESSION_TIMEOUT_MS)`| the function itself, in `test.uts.helpers.proxy`, for the rare case that wants a session the fixture will not close |
372
+
|`session.session_id`, `session.proxy_host`, `session.proxy_port`| what a spec reads off its `session`. The host is always `localhost`|
373
+
|`session.add_rules(rules, position='append')`| rules added while the session runs. `position='prepend'` puts them ahead of the ones already there, which is how a spec faults traffic only once the client has reached some state |
374
+
|`session.trigger_action(action)`| the imperative half — `{'type': 'disconnect'}`, `{'type': 'close', 'closeCode': 1000}`, `inject_to_client`. 409 from the control API when no connection is open |
375
+
|`session.get_log()`| every event, in order, as the dictionaries the control API sends: `type`, `method`, `path`, `status`, `direction`, `queryParams`, `message`, `ruleMatched`. The field names are the ones a specification's assertions are written against, so they are not renamed |
376
+
|`session.close()`| best effort and never raises; the fixture calls it for you |
377
+
|`ensure_proxy()` / `stop_proxy()`| start the control process and reap it. Only the `proxy_control` fixture should need them |
378
+
|`PROXY_VERSION`, `ARCHIVE_CHECKSUMS`, `RELEASE_URL`| the pinned release and the sha256 of each platform's archive. Moving the pin means new checksums, copied from the release's own `checksums.txt`|
379
+
|`SESSION_TIMEOUT_MS` (120000) | the session's **idle** auto-cleanup timer, passed as `timeoutMs`|
380
+
|`SUITE_TIMEOUT` (300) in the package `conftest.py`| the per-test timeout for this package |
381
+
|`UTS_PROXY_LOCAL_PATH`| a locally built binary, or a `.tar.gz` holding one, in place of the pinned release |
382
+
|`UTS_PROXY_CONTROL_URL`| a control API already running, which is then neither started nor stopped by the suite |
383
+
384
+
Everything but the two fixtures is in `test.uts.helpers.proxy`. `http_requests` and
385
+
`http_responses` in the example below are the derived file's own log filters, defined
386
+
at the top of it, because every test in the file reads the log the same two ways.
0 commit comments