Compare commits

...
Author SHA1 Message Date
Cursor AgentandClaude f0b888ffd3 tests: de-duplicate online scoring API format checks
Refactor repeated score request format tests into a shared assertion helper and parametrized cases in bi-encoder and cross-encoder online suites, reducing bloat while preserving coverage.

Co-authored-by: Claude <noreply@anthropic.com>

Signed-off-by: Cursor Agent <cursoragent@cursor.com>
2026-03-26 22:54:25 +00:00
2 changed files with 182 additions and 402 deletions
@@ -26,6 +26,25 @@ TEXTS_2 = [
] ]
def _assert_score_output_matches_hf(hf_model, server: RemoteOpenAIServer,
payload: dict, text_pairs: list[list[str]]):
score_response = requests.post(
server.url_for("score"),
json={"model": MODEL_NAME, **payload},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
assert len(vllm_outputs) == len(hf_outputs)
for hf_output, vllm_output in zip(hf_outputs, vllm_outputs):
assert hf_output == pytest.approx(vllm_output, rel=0.01)
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def server(): def server():
args = ["--enforce-eager", "--max-model-len", "100", "--dtype", DTYPE] args = ["--enforce-eager", "--max-model-len", "100", "--dtype", DTYPE]
@@ -44,207 +63,78 @@ def hf_model():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_score_api_queries_str_1_documents_str_1( @pytest.mark.parametrize(
hf_model, server: RemoteOpenAIServer ("payload", "text_pairs"),
): [
score_response = requests.post( pytest.param(
server.url_for("score"), {
json={ "queries": TEXTS_1[0],
"model": MODEL_NAME, "documents": TEXTS_2[0],
"queries": TEXTS_1[0], },
"documents": TEXTS_2[0], [[TEXTS_1[0], TEXTS_2[0]]],
}, id="queries-str-documents-str",
) ),
score_response.raise_for_status() pytest.param(
score = ScoreResponse.model_validate(score_response.json()) {
"queries": TEXTS_1[0],
assert score.id is not None "documents": TEXTS_2,
assert score.data is not None },
assert len(score.data) == 1 [
[TEXTS_1[0], TEXTS_2[0]],
vllm_outputs = [d.score for d in score.data] [TEXTS_1[0], TEXTS_2[1]],
hf_outputs = hf_model.predict([[TEXTS_1[0], TEXTS_2[0]]]).tolist() ],
id="queries-str-documents-list",
for i in range(len(vllm_outputs)): ),
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01) pytest.param(
{
"queries": TEXTS_1,
@pytest.mark.asyncio "documents": TEXTS_2,
async def test_score_api_queries_str_1_documents_str_n( },
hf_model, server: RemoteOpenAIServer [
): [TEXTS_1[0], TEXTS_2[0]],
text_pairs = [ [TEXTS_1[1], TEXTS_2[1]],
[TEXTS_1[0], TEXTS_2[0]], ],
[TEXTS_1[0], TEXTS_2[1]], id="queries-list-documents-list",
] ),
pytest.param(
score_response = requests.post( {
server.url_for("score"), "queries": TEXTS_1,
json={ "items": TEXTS_2,
"model": MODEL_NAME, },
"queries": TEXTS_1[0], [
"documents": TEXTS_2, [TEXTS_1[0], TEXTS_2[0]],
}, [TEXTS_1[1], TEXTS_2[1]],
) ],
score_response.raise_for_status() id="queries-list-items-list",
score = ScoreResponse.model_validate(score_response.json()) ),
pytest.param(
assert score.id is not None {
assert score.data is not None "text_1": TEXTS_1,
assert len(score.data) == 2 "text_2": TEXTS_2,
},
vllm_outputs = [d.score for d in score.data] [
hf_outputs = hf_model.predict(text_pairs).tolist() [TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
for i in range(len(vllm_outputs)): ],
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01) id="text-1-vs-text-2",
),
pytest.param(
@pytest.mark.asyncio {
async def test_score_api_queries_str_n_documents_str_n( "data_1": TEXTS_1,
hf_model, server: RemoteOpenAIServer "data_2": TEXTS_2,
): },
text_pairs = [ [
[TEXTS_1[0], TEXTS_2[0]], [TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]], [TEXTS_1[1], TEXTS_2[1]],
] ],
id="data-1-vs-data-2",
score_response = requests.post( ),
server.url_for("score"), ],
json={ )
"model": MODEL_NAME, async def test_score_api_request_formats(hf_model, server: RemoteOpenAIServer,
"queries": TEXTS_1, payload: dict,
"documents": TEXTS_2, text_pairs: list[list[str]]):
}, _assert_score_output_matches_hf(hf_model, server, payload, text_pairs)
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_queries_vs_documents(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"queries": TEXTS_1,
"documents": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_queries_vs_items(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"queries": TEXTS_1,
"items": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_text_1_vs_text_2(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"text_1": TEXTS_1,
"text_2": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_data_1_vs_data_2(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"data_1": TEXTS_1,
"data_2": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio @pytest.mark.asyncio
@@ -28,6 +28,25 @@ TEXTS_2 = [
] ]
def _assert_score_output_matches_hf(hf_model, server: RemoteOpenAIServer,
payload: dict, text_pairs: list[list[str]]):
score_response = requests.post(
server.url_for("score"),
json={"model": MODEL_NAME, **payload},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
assert len(vllm_outputs) == len(hf_outputs)
for hf_output, vllm_output in zip(hf_outputs, vllm_outputs):
assert hf_output == pytest.approx(vllm_output, rel=0.01)
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def server(): def server():
args = ["--enforce-eager", "--max-model-len", "100", "--dtype", DTYPE] args = ["--enforce-eager", "--max-model-len", "100", "--dtype", DTYPE]
@@ -61,207 +80,78 @@ async def test_basic(server: RemoteOpenAIServer):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_score_api_queries_str_1_documents_str_1( @pytest.mark.parametrize(
hf_model, server: RemoteOpenAIServer ("payload", "text_pairs"),
): [
score_response = requests.post( pytest.param(
server.url_for("score"), {
json={ "queries": TEXTS_1[0],
"model": MODEL_NAME, "documents": TEXTS_2[0],
"queries": TEXTS_1[0], },
"documents": TEXTS_2[0], [[TEXTS_1[0], TEXTS_2[0]]],
}, id="queries-str-documents-str",
) ),
score_response.raise_for_status() pytest.param(
score = ScoreResponse.model_validate(score_response.json()) {
"queries": TEXTS_1[0],
assert score.id is not None "documents": TEXTS_2,
assert score.data is not None },
assert len(score.data) == 1 [
[TEXTS_1[0], TEXTS_2[0]],
vllm_outputs = [d.score for d in score.data] [TEXTS_1[0], TEXTS_2[1]],
hf_outputs = hf_model.predict([[TEXTS_1[0], TEXTS_2[0]]]).tolist() ],
id="queries-str-documents-list",
for i in range(len(vllm_outputs)): ),
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01) pytest.param(
{
"queries": TEXTS_1,
@pytest.mark.asyncio "documents": TEXTS_2,
async def test_score_api_queries_str_1_documents_str_n( },
hf_model, server: RemoteOpenAIServer [
): [TEXTS_1[0], TEXTS_2[0]],
text_pairs = [ [TEXTS_1[1], TEXTS_2[1]],
[TEXTS_1[0], TEXTS_2[0]], ],
[TEXTS_1[0], TEXTS_2[1]], id="queries-list-documents-list",
] ),
pytest.param(
score_response = requests.post( {
server.url_for("score"), "queries": TEXTS_1,
json={ "items": TEXTS_2,
"model": MODEL_NAME, },
"queries": TEXTS_1[0], [
"documents": TEXTS_2, [TEXTS_1[0], TEXTS_2[0]],
}, [TEXTS_1[1], TEXTS_2[1]],
) ],
score_response.raise_for_status() id="queries-list-items-list",
score = ScoreResponse.model_validate(score_response.json()) ),
pytest.param(
assert score.id is not None {
assert score.data is not None "text_1": TEXTS_1,
assert len(score.data) == 2 "text_2": TEXTS_2,
},
vllm_outputs = [d.score for d in score.data] [
hf_outputs = hf_model.predict(text_pairs).tolist() [TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
for i in range(len(vllm_outputs)): ],
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01) id="text-1-vs-text-2",
),
pytest.param(
@pytest.mark.asyncio {
async def test_score_api_queries_str_n_documents_str_n( "data_1": TEXTS_1,
hf_model, server: RemoteOpenAIServer "data_2": TEXTS_2,
): },
text_pairs = [ [
[TEXTS_1[0], TEXTS_2[0]], [TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]], [TEXTS_1[1], TEXTS_2[1]],
] ],
id="data-1-vs-data-2",
score_response = requests.post( ),
server.url_for("score"), ],
json={ )
"model": MODEL_NAME, async def test_score_api_request_formats(hf_model, server: RemoteOpenAIServer,
"queries": TEXTS_1, payload: dict,
"documents": TEXTS_2, text_pairs: list[list[str]]):
}, _assert_score_output_matches_hf(hf_model, server, payload, text_pairs)
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_queries_vs_documents(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"queries": TEXTS_1,
"documents": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_queries_vs_items(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"queries": TEXTS_1,
"items": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_text_1_vs_text_2(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"text_1": TEXTS_1,
"text_2": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio
async def test_score_api_data_1_vs_data_2(hf_model, server: RemoteOpenAIServer):
text_pairs = [
[TEXTS_1[0], TEXTS_2[0]],
[TEXTS_1[1], TEXTS_2[1]],
]
score_response = requests.post(
server.url_for("score"),
json={
"model": MODEL_NAME,
"data_1": TEXTS_1,
"data_2": TEXTS_2,
},
)
score_response.raise_for_status()
score = ScoreResponse.model_validate(score_response.json())
assert score.id is not None
assert score.data is not None
assert len(score.data) == 2
vllm_outputs = [d.score for d in score.data]
hf_outputs = hf_model.predict(text_pairs).tolist()
for i in range(len(vllm_outputs)):
assert hf_outputs[i] == pytest.approx(vllm_outputs[i], rel=0.01)
@pytest.mark.asyncio @pytest.mark.asyncio