From d00ce29d89c7badf5fb6ca511cc591fd9c62a85f Mon Sep 17 00:00:00 2001 From: Chauncey Date: Thu, 23 Oct 2025 18:10:06 +0800 Subject: [PATCH] [CI] Reorganize entrypoints tests (#27403) Signed-off-by: chaunceyjiang --- tests/entrypoints/openai/test_chat.py | 139 ----------------- .../test_completion_with_function_calling.py | 141 ++++++++++++++++++ 2 files changed, 141 insertions(+), 139 deletions(-) diff --git a/tests/entrypoints/openai/test_chat.py b/tests/entrypoints/openai/test_chat.py index fa8ae55d14a2..d25958f602b3 100644 --- a/tests/entrypoints/openai/test_chat.py +++ b/tests/entrypoints/openai/test_chat.py @@ -599,145 +599,6 @@ async def test_structured_outputs_choice_chat_logprobs( assert item.logprob >= -9999.0, f"Failed (top_logprobs={top_logprobs})" -@pytest.mark.asyncio -async def test_named_tool_use( - client: openai.AsyncOpenAI, - sample_json_schema, -): - messages = [ - {"role": "system", "content": "you are a helpful assistant"}, - { - "role": "user", - "content": ( - "Give an example JSON for an employee profile using the specified tool." - ), - }, - ] - tools = [ - { - "type": "function", - "function": { - "name": "dummy_function_name", - "description": "This is a dummy function", - "parameters": sample_json_schema, - }, - } - ] - tool_choice = {"type": "function", "function": {"name": "dummy_function_name"}} - - # non-streaming - - chat_completion = await client.chat.completions.create( - model=MODEL_NAME, - messages=messages, - max_completion_tokens=1000, - tools=tools, - tool_choice=tool_choice, - ) - message = chat_completion.choices[0].message - assert len(message.content) == 0 - json_string = message.tool_calls[0].function.arguments - json1 = json.loads(json_string) - jsonschema.validate(instance=json1, schema=sample_json_schema) - - messages.append({"role": "assistant", "content": json_string}) - messages.append( - {"role": "user", "content": "Give me another one with a different name and age"} - ) - - # streaming - - stream = await client.chat.completions.create( - model=MODEL_NAME, - messages=messages, - max_completion_tokens=1000, - tools=tools, - tool_choice=tool_choice, - stream=True, - ) - - output = [] - finish_reason_count = 0 - async for chunk in stream: - delta = chunk.choices[0].delta - if delta.role: - assert delta.role == "assistant" - assert delta.content is None or len(delta.content) == 0 - if delta.tool_calls: - output.append(delta.tool_calls[0].function.arguments) - if chunk.choices[0].finish_reason is not None: - finish_reason_count += 1 - # finish reason should only return in last block - assert finish_reason_count == 1 - json2 = json.loads("".join(output)) - jsonschema.validate(instance=json2, schema=sample_json_schema) - assert json1["name"] != json2["name"] - assert json1["age"] != json2["age"] - - -@pytest.mark.asyncio -async def test_inconsistent_tool_choice_and_tools( - client: openai.AsyncOpenAI, sample_json_schema -): - messages = [ - {"role": "system", "content": "you are a helpful assistant"}, - { - "role": "user", - "content": f"Give an example JSON for an employee profile that " - f"fits this schema: {sample_json_schema}", - }, - ] - - with pytest.raises(openai.BadRequestError): - await client.chat.completions.create( - model=MODEL_NAME, - messages=messages, - max_completion_tokens=1000, - tool_choice={ - "type": "function", - "function": {"name": "dummy_function_name"}, - }, - ) - - with pytest.raises(openai.BadRequestError): - await client.chat.completions.create( - model=MODEL_NAME, - messages=messages, - max_completion_tokens=1000, - tools=[ - { - "type": "function", - "function": { - "name": "dummy_function_name", - "description": "This is a dummy function", - "parameters": sample_json_schema, - }, - } - ], - tool_choice={ - "type": "function", - "function": {"name": "nondefined_function_name"}, - }, - ) - with pytest.raises(openai.BadRequestError): - await client.chat.completions.create( - model=MODEL_NAME, - messages=messages, - max_completion_tokens=1000, - tools=[ - { - "type": "function", - "function": { - "name": "dummy_function_name", - "description": "This is a dummy function", - "parameters": sample_json_schema, - }, - } - ], - tool_choice={}, - ) - - @pytest.mark.asyncio async def test_response_format_json_object(client: openai.AsyncOpenAI): for _ in range(2): diff --git a/tests/entrypoints/openai/test_completion_with_function_calling.py b/tests/entrypoints/openai/test_completion_with_function_calling.py index f6453af89ff7..020cb6af2db6 100644 --- a/tests/entrypoints/openai/test_completion_with_function_calling.py +++ b/tests/entrypoints/openai/test_completion_with_function_calling.py @@ -2,7 +2,9 @@ # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import datetime +import json +import jsonschema import openai # use the official client for correctness check import pytest import pytest_asyncio @@ -341,3 +343,142 @@ async def test_no_args_tool_call( else: # No tool called — just print model's direct reply assert message.content is not None + + +@pytest.mark.asyncio +async def test_named_tool_use( + client: openai.AsyncOpenAI, + sample_json_schema, +): + messages = [ + {"role": "system", "content": "you are a helpful assistant"}, + { + "role": "user", + "content": ( + "Give an example JSON for an employee profile using the specified tool." + ), + }, + ] + tools = [ + { + "type": "function", + "function": { + "name": "dummy_function_name", + "description": "This is a dummy function", + "parameters": sample_json_schema, + }, + } + ] + tool_choice = {"type": "function", "function": {"name": "dummy_function_name"}} + + # non-streaming + + chat_completion = await client.chat.completions.create( + model=MODEL_NAME, + messages=messages, + max_completion_tokens=1000, + tools=tools, + tool_choice=tool_choice, + ) + message = chat_completion.choices[0].message + assert len(message.content) == 0 + json_string = message.tool_calls[0].function.arguments + json1 = json.loads(json_string) + jsonschema.validate(instance=json1, schema=sample_json_schema) + + messages.append({"role": "assistant", "content": json_string}) + messages.append( + {"role": "user", "content": "Give me another one with a different name and age"} + ) + + # streaming + + stream = await client.chat.completions.create( + model=MODEL_NAME, + messages=messages, + max_completion_tokens=1000, + tools=tools, + tool_choice=tool_choice, + stream=True, + ) + + output = [] + finish_reason_count = 0 + async for chunk in stream: + delta = chunk.choices[0].delta + if delta.role: + assert delta.role == "assistant" + assert delta.content is None or len(delta.content) == 0 + if delta.tool_calls: + output.append(delta.tool_calls[0].function.arguments) + if chunk.choices[0].finish_reason is not None: + finish_reason_count += 1 + # finish reason should only return in last block + assert finish_reason_count == 1 + json2 = json.loads("".join(output)) + jsonschema.validate(instance=json2, schema=sample_json_schema) + assert json1["name"] != json2["name"] + assert json1["age"] != json2["age"] + + +@pytest.mark.asyncio +async def test_inconsistent_tool_choice_and_tools( + client: openai.AsyncOpenAI, sample_json_schema +): + messages = [ + {"role": "system", "content": "you are a helpful assistant"}, + { + "role": "user", + "content": f"Give an example JSON for an employee profile that " + f"fits this schema: {sample_json_schema}", + }, + ] + + with pytest.raises(openai.BadRequestError): + await client.chat.completions.create( + model=MODEL_NAME, + messages=messages, + max_completion_tokens=1000, + tool_choice={ + "type": "function", + "function": {"name": "dummy_function_name"}, + }, + ) + + with pytest.raises(openai.BadRequestError): + await client.chat.completions.create( + model=MODEL_NAME, + messages=messages, + max_completion_tokens=1000, + tools=[ + { + "type": "function", + "function": { + "name": "dummy_function_name", + "description": "This is a dummy function", + "parameters": sample_json_schema, + }, + } + ], + tool_choice={ + "type": "function", + "function": {"name": "nondefined_function_name"}, + }, + ) + with pytest.raises(openai.BadRequestError): + await client.chat.completions.create( + model=MODEL_NAME, + messages=messages, + max_completion_tokens=1000, + tools=[ + { + "type": "function", + "function": { + "name": "dummy_function_name", + "description": "This is a dummy function", + "parameters": sample_json_schema, + }, + } + ], + tool_choice={}, + )