SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
5.8 KB · 81 lines python
Raw Blame History
1"""Smoke tests for POST /v1beta/models/{model}:generateContent (gemini-3.5-flash-lite, maxOutputTokens <= 32).23Verified live 2026-09-18. Each test < $0.0001. Paced for the free tier (see _core_helpers.call).4"""5from __future__ import annotations67from tests.gemini._core_helpers import call, gc, text_of, user8910def test_minimal_shape(gemini, models):11    st, body, hdrs = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 16}}, note="test_generate_content minimal")12    assert st == 200, body13    c = body["candidates"][0]14    assert c["finishReason"] == "STOP" and c["index"] == 0 and c["content"]["role"] == "model"15    assert "OK" in text_of(body)16    assert c["content"]["parts"][-1].get("thoughtSignature"), "Gemini 3 attaches a thoughtSignature to the last part"17    u = body["usageMetadata"]18    assert {"promptTokenCount", "candidatesTokenCount", "totalTokenCount", "promptTokensDetails", "serviceTier"} <= u.keys()19    assert u["serviceTier"] == "standard" and u["promptTokensDetails"][0]["modality"] == "TEXT"20    assert body["modelVersion"] == models["gemini"] and body["responseId"]212223def test_system_instruction_and_multiturn(gemini, models):24    body = {"systemInstruction": {"parts": [{"text": "Answer with one word."}]},25            "contents": [{"role": "user", "parts": [{"text": "My name is Atlas."}]}, {"role": "model", "parts": [{"text": "Noted."}]}, {"role": "user", "parts": [{"text": "What is my name?"}]}],26            "generationConfig": {"maxOutputTokens": 16, "temperature": 1.0, "topP": 0.95, "topK": 64, "seed": 7, "stopSequences": ["STOP"]}}27    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), body, note="test_generate_content system+multiturn")28    assert st == 200, resp29    assert "atlas" in text_of(resp).lower()303132def test_snake_case_aliases_accepted(gemini, models):33    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"system_instruction": {"parts": [{"text": "Answer with OK."}]}, "contents": user("Hi"), "generation_config": {"max_output_tokens": 8}}, note="test_generate_content snake_case")34    assert st == 200, resp353637def test_model_turn_last_rejected(gemini, models):38    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": [{"role": "model", "parts": [{"text": "hi"}]}], "generationConfig": {"maxOutputTokens": 8}}, note="test_generate_content model-last")39    assert st == 400 and resp["error"]["status"] == "INVALID_ARGUMENT"40    assert "model turn" in resp["error"]["message"]414243def test_validation_errors_verbatim(gemini, models):44    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("x"), "generationConfig": {"maxOutputTokens": 8, "temperature": 2.5}}, note="test_generate_content temperature range")45    assert st == 400 and "temperature must be in the range [0.0, 2.0]" in resp["error"]["message"]46    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("x"), "generationConfig": {"maxOutputTokens": 8, "bogusField": 1}}, note="test_generate_content unknown field")47    assert st == 400 and 'Unknown name "bogusField"' in resp["error"]["message"]48    assert resp["error"]["details"][0]["@type"].endswith("google.rpc.BadRequest")495051def test_unsupported_features_on_gemini3(gemini, models):52    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 8, "candidateCount": 2}}, note="test_generate_content candidateCount 2")53    assert st == 400 and "Multiple candidates is not enabled" in resp["error"]["message"]54    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "generationConfig": {"maxOutputTokens": 8, "responseLogprobs": True, "logprobs": 2}}, note="test_generate_content logprobs")55    assert st == 400 and "Logprobs is not enabled" in resp["error"]["message"]565758def test_max_tokens_finish_reason(gemini, models):59    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Write a 300 word essay about rivers."), "generationConfig": {"maxOutputTokens": 8}}, note="test_generate_content MAX_TOKENS")60    assert st == 200 and resp["candidates"][0]["finishReason"] == "MAX_TOKENS"616263def test_service_tier_echo(gemini, models):64    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "serviceTier": "standard", "labels": {"env": "atlas-test"}, "generationConfig": {"maxOutputTokens": 8}}, note="test_generate_content serviceTier")65    assert st == 200 and resp["usageMetadata"]["serviceTier"] == "standard"666768def test_safety_ratings_present_when_settings_sent(gemini, models):69    cats = ["HARM_CATEGORY_HARASSMENT", "HARM_CATEGORY_HATE_SPEECH", "HARM_CATEGORY_SEXUALLY_EXPLICIT", "HARM_CATEGORY_DANGEROUS_CONTENT"]70    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("Reply with OK."), "safetySettings": [{"category": c, "threshold": "BLOCK_LOW_AND_ABOVE"} for c in cats], "generationConfig": {"maxOutputTokens": 8}}, note="test_generate_content safety")71    assert st == 200, resp72    ratings = resp["candidates"][0]["safetyRatings"]73    assert {r["category"] for r in ratings} == set(cats) and all(r["probability"] in ("NEGLIGIBLE", "LOW", "MEDIUM", "HIGH") for r in ratings)74    st, resp, _ = call(gemini, "POST", gc(models["gemini"]), {"contents": user("x"), "safetySettings": [{"category": "HARM_CATEGORY_TOXICITY", "threshold": "BLOCK_NONE"}], "generationConfig": {"maxOutputTokens": 8}}, note="test_generate_content PaLM category")75    assert st == 400 and "element predicate failed" in resp["error"]["message"]767778def test_unknown_model_404(gemini):79    st, resp, _ = call(gemini, "POST", gc("gemini-99-ultra"), {"contents": user("x")}, note="test_generate_content 404")80    assert st == 404 and resp["error"]["status"] == "NOT_FOUND" and "ListModels" in resp["error"]["message"]81