"""cachedContents: validation errors (always), full CRUD only when the account can create caches. On the free tier creation returns 429 TotalCachedContentStorageTokensPerModelFreeTier limit=0 (ACCOUNT_RESTRICTED) and the CRUD test is skipped. Verified 2026-09-18. """ from __future__ import annotations import pytest from tests.gemini._core_helpers import call, gc, user FLASH = "gemini-3.5-flash" FILLER = " ".join(f"Section {i}: The Atlas reference corpus documents the public API surface of large language model providers, including endpoints, parameters, streaming events, objects, errors and pricing." for i in range(1, 121)) def test_create_validation_errors(gemini, models): st, r, _ = call(gemini, "POST", "/v1beta/cachedContents", {"model": f"models/{models['gemini']}", "contents": user("Too small."), "ttl": "60s"}, note="test_caching below min") assert st == 400 and "Cached content is too small" in r["error"]["message"] and "min_total_token_count=" in r["error"]["message"] st, r, _ = call(gemini, "POST", "/v1beta/cachedContents", {"contents": user("x")}, note="test_caching no model") assert st == 400 and "models/{model_name}" in r["error"]["message"] def test_v1_has_no_cached_contents(gemini): st, body, _ = call(gemini, "GET", "/v1/cachedContents?pageSize=1", None, note="test_caching v1 route") assert st == 404 def test_cache_crud_or_restricted(gemini): st, cache, _ = call(gemini, "POST", "/v1beta/cachedContents", {"model": f"models/{FLASH}", "displayName": "atlas-test", "ttl": "120s", "contents": [{"role": "user", "parts": [{"text": FILLER}]}]}, note="test_caching create") if st == 429 and "FreeTier" in cache.get("error", {}).get("message", ""): pytest.skip("ACCOUNT_RESTRICTED: explicit caching quota is 0 on the free tier") assert st == 200, cache name = cache["name"] try: assert name.startswith("cachedContents/") and cache["expireTime"] and cache["usageMetadata"]["totalTokenCount"] >= 1024 st, r, _ = call(gemini, "POST", gc(FLASH), {"contents": user("Reply with OK."), "cachedContent": name, "generationConfig": {"maxOutputTokens": 8}}, note="test_caching use") assert st == 200 and r["usageMetadata"]["cachedContentTokenCount"] >= 1024 st, r, _ = call(gemini, "GET", f"/v1beta/{name}", None, note="test_caching get") assert st == 200 and r["name"] == name st, r, _ = call(gemini, "PATCH", f"/v1beta/{name}", {"ttl": "300s"}, note="test_caching patch") assert st == 200 and r["expireTime"] st, r, _ = call(gemini, "GET", "/v1beta/cachedContents?pageSize=5", None, note="test_caching list") assert st == 200 and any(c["name"] == name for c in r.get("cachedContents", [])) finally: st, _, _ = call(gemini, "DELETE", f"/v1beta/{name}", None, note="test_caching delete") assert st == 200