Skip to content

Commit 661c031

Browse files
davidxiahmellor
authored andcommitted
[Bugfix] make test_openai_schema.py pass (vllm-project#18224)
Signed-off-by: David Xia <david@davidxia.com> Co-authored-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Signed-off-by: minpeter <kali2005611@gmail.com>
1 parent f2baeae commit 661c031

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

.buildkite/test-pipeline.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ steps:
126126
- pytest -v -s entrypoints/llm/test_generate.py # it needs a clean process
127127
- pytest -v -s entrypoints/llm/test_generate_multiple_loras.py # it needs a clean process
128128
- VLLM_USE_V1=0 pytest -v -s entrypoints/llm/test_guided_generate.py # it needs a clean process
129-
- pytest -v -s entrypoints/openai --ignore=entrypoints/openai/test_oot_registration.py --ignore=entrypoints/openai/test_chat_with_tool_reasoning.py --ignore=entrypoints/openai/correctness/ --ignore=entrypoints/openai/test_openai_schema.py
129+
- pytest -v -s entrypoints/openai --ignore=entrypoints/openai/test_oot_registration.py --ignore=entrypoints/openai/test_chat_with_tool_reasoning.py --ignore=entrypoints/openai/correctness/
130130
- pytest -v -s entrypoints/test_chat_utils.py
131131
- VLLM_USE_V1=0 pytest -v -s entrypoints/offline_mode # Needs to avoid interference with other tests
132132

tests/entrypoints/openai/test_openai_schema.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# SPDX-License-Identifier: Apache-2.0
2+
from typing import Final
3+
24
import pytest
35
import schemathesis
6+
from hypothesis import settings
47
from schemathesis import GenerationConfig
58

69
from ...utils import RemoteOpenAIServer
@@ -9,6 +12,8 @@
912

1013
MODEL_NAME = "HuggingFaceTB/SmolVLM-256M-Instruct"
1114
MAXIMUM_IMAGES = 2
15+
DEFAULT_TIMEOUT_SECONDS: Final[int] = 10
16+
LONG_TIMEOUT_SECONDS: Final[int] = 60
1217

1318

1419
@pytest.fixture(scope="module")
@@ -42,8 +47,58 @@ def get_schema(server):
4247
schema = schemathesis.from_pytest_fixture("get_schema")
4348

4449

50+
@schemathesis.hook
51+
def before_generate_case(context: schemathesis.hooks.HookContext, strategy):
52+
op = context.operation
53+
assert op is not None
54+
55+
def no_file_type(case: schemathesis.models.Case):
56+
"""
57+
This filter skips test cases for the `POST /tokenize` endpoint where the
58+
HTTP request body uses `"type": "file"` in any message's content.
59+
We expect these cases to fail because that type isn't implemented here
60+
https://github.com/vllm-project/vllm/blob/0b34593017953051b3225b1483ce0f4670e3eb0e/vllm/entrypoints/chat_utils.py#L1038-L1095
61+
62+
Example test cases that are skipped:
63+
curl -X POST -H 'Content-Type: application/json' \
64+
-d '{"messages": [{"role": "assistant"}, {"content": [{"file": {}, "type": "file"}], "role": "user"}]}' \
65+
http://localhost:8000/tokenize
66+
67+
curl -X POST -H 'Content-Type: application/json' \
68+
-d '{"messages": [{"content": [{"file": {}, "type": "file"}], "role": "user"}]}' \
69+
http://localhost:8000/tokenize
70+
""" # noqa: E501
71+
if (op.method.lower() == "post" and op.path == "/tokenize"
72+
and hasattr(case, "body") and isinstance(case.body, dict)
73+
and "messages" in case.body
74+
and isinstance(case.body["messages"], list)
75+
and len(case.body["messages"]) > 0):
76+
for message in case.body["messages"]:
77+
if not isinstance(message, dict):
78+
continue
79+
content = message.get("content", [])
80+
if not isinstance(content, list) or len(content) == 0:
81+
continue
82+
if any(item.get("type") == "file" for item in content):
83+
return False
84+
return True
85+
86+
return strategy.filter(no_file_type)
87+
88+
4589
@schema.parametrize()
4690
@schema.override(headers={"Content-Type": "application/json"})
91+
@settings(deadline=LONG_TIMEOUT_SECONDS * 1000)
4792
def test_openapi_stateless(case: schemathesis.Case):
93+
key = (
94+
case.operation.method.upper(),
95+
case.operation.path,
96+
)
97+
timeout = {
98+
# requires a longer timeout
99+
("POST", "/v1/chat/completions"):
100+
LONG_TIMEOUT_SECONDS,
101+
}.get(key, DEFAULT_TIMEOUT_SECONDS)
102+
48103
#No need to verify SSL certificate for localhost
49-
case.call_and_validate(verify=False)
104+
case.call_and_validate(verify=False, timeout=timeout)

0 commit comments

Comments
 (0)