litellm/tests/unit/AGENTS.md
Mateo Wang 77064d6c70
feat(vector_stores): add OpenSearch k-NN search as a vector store provider (#47759)
* feat(vector_stores): add Amazon OpenSearch as a vector store provider

* feat(ui): add Amazon OpenSearch to the vector store provider dropdown

* feat(vector_stores): add OpenSearch k-NN search as a vector store provider

* test(vector_stores): hold the OpenSearch provider tests alone for the first review

The provider source comes back in the next commits on this PR

* ci(tests): run the OpenSearch vector store unit tests

* fix(vector_stores): sign on.aws and FIPS OpenSearch hosts and reject missing AWS credentials before embedding

* fix(vector_stores): regenerate provider endpoint support for opensearch

* fix(vector_stores): keep opensearch retrieve, update, and delete off the index and refuse half-set AWS keys and per-account endpoints

* fix(vector_stores): return only scalar opensearch attributes and keep credential source output out of 401s

* test(vector_stores): inject a failing opensearch credential source instead of running a shell

* fix(vector_stores): sign opensearch for the endpoint's region, refuse list, add opensearch_index_name, honor drop_params

* fix(vector_stores): refuse a caller-chosen opensearch_index_name on search and rag query

* fix(vector_stores): refuse opensearch_index_name only on OpenSearch stores, keep the old 400 text

Other providers drop the key again as they did before OpenSearch support, and the four embedding keys keep their original error sentence.

* fix(vector_stores): refuse a caller index on slash-form OpenSearch stores
2026-10-29 08:15:05 -07:00

2.3 KiB

tests/unit

In-process. No network or subprocess. interactions/test_openapi_compliance.py reads the spec snapshot beside it, and only the interactions-spec-canary workflow passes --interactions-spec-url (registered in interactions/conftest.py, so name that file or directory on the command line) with ai.google.dev allowed, to run the same tests against Google's live spec

Unit tests must not depend on the current time or execution speed. Use fixed timestamps for fixtures and controlled clocks for time-dependent behavior. Incidental clock reads inside production code are allowed

A unix socket goes under the socket_dir or socket_path fixture, never tmp_path, whose paths run past macOS's 104-byte AF_UNIX limit and fail only on a Mac. Code that opens a socket in its own tempfile directory runs under socket_tempdir

What good looks like

def test_send_result_same_version_is_identity_passthrough():
    rpc = _rpc(V03_MESSAGE)
    out = normalize_jsonrpc_response(rpc, "0.3", method="message/send")
    assert out is rpc

is, because == passes on a copy. Many inputs: parametrize (test_an_incomplete_reservation_accrues_nothing, fifteen cases, fifteen results)

No doubles on our own code

with patch.object(streamer, "_group_by_date") as mock_group, patch.object(streamer, "_send_daily_batch") as mock_send:
    mock_group.return_value = {"2025-01-19": pl.DataFrame({"test": ["data1"]}), "2025-01-20": pl.DataFrame({"test": ["data2"]})}
    streamer.send_batched(pl.DataFrame({"test": ["data"]}), "replace_hourly")
    assert mock_send.call_count == 2

Green if send_batched drops every row. pydantic doubles in 12 of 203 files, fastapi 11 of 594. tests/test_litellm 59 percent. Exception: the count is the behaviour (test_dual_cache_async_batch_get_cache_coalesces_concurrent_redis_reads, fifty readers, call_count == 1)

Where it goes

tests/unit/<path> mirrors litellm/<path>, so a changed file selects its tests by path, not a mapping file. New unit tests go here

A new directory under tests/unit runs in CI only once a shard in .github/workflows/test-unit.yml names it. pytest tests/unit/test_assert_ci_coverage.py checks that, so run it before you push

Writing it so a human can read it

A class only when tests share an arrange