test(recorded): add client cassette coverage (3/5)#1976
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
6fec9aa to
9cad57c
Compare
dc3a4a7 to
8000a8e
Compare
Greptile SummaryThis PR adds client-level cassette coverage for OpenAI chat and embeddings, forming part 3 of a 5-PR stack that decomposes recorded end-to-end replay coverage into reviewable slices. All cassettes are correctly sanitized (no secrets, volatile fields normalized) and the VCR fixture plumbing — cassette directory, body matcher, serializer — aligns with the harness established in earlier PRs.
|
| Filename | Overview |
|---|---|
| tests/recorded/clients/init.py | Package init file with license header and docstring; no functional code. |
| tests/recorded/clients/test_openai_chat.py | Async VCR test for OpenAI chat; constructs OpenAICompatibleClient with an externally-managed httpx client, calls generate_async, and validates result shape against the cassette response. |
| tests/recorded/clients/test_openai_embeddings.py | Synchronous VCR test for OpenAI embeddings; directly instantiates OpenAIEmbeddingModel and validates that the decoded embedding vector has the expected dimension (1536). |
| tests/recorded/clients/cassettes/test_openai_chat/test_openai_chat_generate_text.yaml | Cassette for the chat test; volatile fields (response id, system_fingerprint) are correctly normalized and no secrets are present. |
| tests/recorded/clients/cassettes/test_openai_embeddings/test_openai_embeddings_sync.yaml | Cassette for the embeddings test; stores a single base64-encoded 1536-dim embedding; Authorization header is absent as expected after sanitization. |
| tests/recorded/clients/configs/openai_chat_config/config.yml | Minimal passthrough chat config referencing gpt-4o-mini; added in this PR but not yet loaded by any test in this slice of the stack. |
| tests/recorded/clients/configs/openai_embeddings_config/config.yml | Minimal embeddings config for text-embedding-3-small; added in this PR but not yet loaded by any test in this slice of the stack. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Test as Test (pytest)
participant VCR as VCR Cassette
participant Client as OpenAICompatibleClient / OpenAIEmbeddingModel
participant API as OpenAI API (mocked)
Note over Test,API: Replay mode (--block-network)
Test->>VCR: load cassette YAML
VCR-->>Test: cassette ready
alt Chat test (async)
Test->>Client: OpenAICompatibleClient(base_url, api_key, http_client)
Test->>Client: model.generate_async("Say hello in one word")
Client->>VCR: POST /v1/chat/completions
VCR-->>Client: "200 { content: "Hello!" }"
Client-->>Test: GenerationResult
Test->>Test: assert content, finish_reason, request_id, usage
else Embeddings test (sync)
Test->>Client: OpenAIEmbeddingModel("text-embedding-3-small", api_key)
Test->>Client: model.encode(["test"])
Client->>VCR: POST /v1/embeddings
VCR-->>Client: "200 { embedding: base64(...) }"
Client-->>Test: List[List[float]]
Test->>Test: "assert len==1, len(result[0])==1536"
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Test as Test (pytest)
participant VCR as VCR Cassette
participant Client as OpenAICompatibleClient / OpenAIEmbeddingModel
participant API as OpenAI API (mocked)
Note over Test,API: Replay mode (--block-network)
Test->>VCR: load cassette YAML
VCR-->>Test: cassette ready
alt Chat test (async)
Test->>Client: OpenAICompatibleClient(base_url, api_key, http_client)
Test->>Client: model.generate_async("Say hello in one word")
Client->>VCR: POST /v1/chat/completions
VCR-->>Client: "200 { content: "Hello!" }"
Client-->>Test: GenerationResult
Test->>Test: assert content, finish_reason, request_id, usage
else Embeddings test (sync)
Test->>Client: OpenAIEmbeddingModel("text-embedding-3-small", api_key)
Test->>Client: model.encode(["test"])
Client->>VCR: POST /v1/embeddings
VCR-->>Client: "200 { embedding: base64(...) }"
Client-->>Test: List[List[float]]
Test->>Test: "assert len==1, len(result[0])==1536"
end
Reviews (11): Last reviewed commit: "test(recorded): add client cassette cove..." | Re-trigger Greptile
9cad57c to
7310fa7
Compare
8000a8e to
a253ae2
Compare
7310fa7 to
6b783f2
Compare
a253ae2 to
3d1d7ea
Compare
6b783f2 to
e1954d4
Compare
5153569 to
caafb61
Compare
7000fcc to
5571204
Compare
caafb61 to
3136aa1
Compare
5571204 to
fa2ce24
Compare
3136aa1 to
06858a2
Compare
fa2ce24 to
05def3f
Compare
06858a2 to
474d54d
Compare
05def3f to
f912ae5
Compare
474d54d to
36679f9
Compare
Summary
Adds recorded client-level coverage for OpenAI chat and embeddings flows.
Why
Client cassette smoke tests validate that the harness can replay basic provider traffic before the rails API coverage layers on top.
What Changed
Stack Position
Part 3 of 5.
Stack Context
This stack decomposes recorded end-to-end replay coverage into reviewable slices. The PRs should be reviewed against their parent branch in the stack.
Please review each PR against its parent branch, not directly against the root base branch, except for part 1.
stack/recorded-tests-01-harnessdevelopstack/recorded-tests-02-deterministic-library-loadstack/recorded-tests-01-harnessstack/recorded-tests-03-clientsstack/recorded-tests-02-deterministic-library-loadstack/recorded-tests-04-public-apistack/recorded-tests-03-clientsstack/recorded-tests-05-library-railsstack/recorded-tests-04-public-apiValidation