> This page is for version 0.7.0.
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# nemo_gym.server_runtime.testing.session_conformance

Integration test for a resources server's episode session lifecycle.

`check_resources_session_contract` drives the app a server builds through its real HTTP routes and middleware,
in process, the way an environment server calls a deployed server: episode seed, repeated seed, a conflicting seed,
close, repeated close, a close that names another episode, close of a never-seeded session, a seed after close, a
close without the session cookie after a seed whose reply was lost, and optionally a verify after close. Call it from
the server's own tests. Because it goes through the routes, it also catches a route that another registration
shadows.

## Module Contents

### Functions

| Name                                                                                                                        | Description                                                                                         |
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| [`check_resources_session_contract`](#nemo_gym-server_runtime-testing-session_conformance-check_resources_session_contract) | Seed, re-seed, and close a session through `app`, and raise AssertionError on a contract violation. |

### API

```python
nemo_gym.server_runtime.testing.session_conformance.check_resources_session_contract(
    app: fastapi.FastAPI,
    seed: nemo_gym.server_runtime.base_resources_server.ResourcesSeedSessionRequest,
    keeps_state: bool,
    holds_state: collections.abc.Callable[[str], bool] | None = None,
    verify_body: collections.abc.Mapping[str, object] | None = None
) -> None
```

Seed, re-seed, and close a session through `app`, and raise AssertionError on a contract violation.

`seed` must use a `resources_session_id` the app has not seen. With `keeps_state`:

* a seed that names the open session's ID with another episode is refused with 409;
* a close of the closed session that names another episode is refused with 409;
* a seed that arrives after its session closed, or after a close for an ID that was never seeded, is refused
  with 409 while the session is fenced (`session_close_retry_window_seconds`). A server that keeps
  no state has nothing such a seed could recreate.

The check also seeds a second session and drops its cookie, as when the seed's reply is lost, then closes it
without a cookie, as the Environment Server does. That close must succeed. With `holds_state`, a callable that
reports whether the server holds state for a `resources_session_id`, both closes must release that state.

With `verify_body` (requires `keeps_state`), a `/verify` sent with the closed session's cookie must
return a masked sample whose `failure_kind` is `session_lost` or `session_expired`, not a reward of 0.
Pass it for a server whose score depends on per-rollout state.