|
| 1 | +import json |
| 2 | +import os |
| 3 | +import subprocess |
| 4 | +import sys |
| 5 | +from pathlib import Path |
| 6 | + |
| 7 | +import pytest |
| 8 | + |
| 9 | +SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "parallel-mode-test.sh" |
| 10 | + |
| 11 | + |
| 12 | +@pytest.fixture |
| 13 | +def run_comparisons(tmp_path): |
| 14 | + curl = tmp_path / "curl" |
| 15 | + curl.write_text( |
| 16 | + f"#!{sys.executable}\n" |
| 17 | + "import json, os, sys\n" |
| 18 | + "with open(os.environ['REQUEST_LOG'], 'a') as log:\n" |
| 19 | + " log.write(json.dumps(sys.argv[1:]) + '\\n')\n" |
| 20 | + "if os.environ.get('HTTP_FAILURE'):\n" |
| 21 | + " sys.exit(22)\n" |
| 22 | + "body = os.environ.get('RESPONSE_BODY', '[{\"text\": \"content\"}]')\n" |
| 23 | + "if os.environ.get('MISMATCH') and any('parallel/' in arg for arg in sys.argv):\n" |
| 24 | + " body = '[{}, {}]'\n" |
| 25 | + "print(body)\n" |
| 26 | + ) |
| 27 | + curl.chmod(0o755) |
| 28 | + log = tmp_path / "requests.jsonl" |
| 29 | + |
| 30 | + def run(**overrides): |
| 31 | + result = subprocess.run( |
| 32 | + ["bash", str(SCRIPT), "http://single", "http://parallel"], |
| 33 | + env={ |
| 34 | + **os.environ, |
| 35 | + "PATH": f"{tmp_path}:{os.environ['PATH']}", |
| 36 | + "REQUEST_LOG": str(log), |
| 37 | + **overrides, |
| 38 | + }, |
| 39 | + capture_output=True, |
| 40 | + text=True, |
| 41 | + check=False, |
| 42 | + ) |
| 43 | + requests = [json.loads(line) for line in log.read_text().splitlines()] |
| 44 | + return result, requests |
| 45 | + |
| 46 | + return run |
| 47 | + |
| 48 | + |
| 49 | +def test_comparisons_send_valid_options_to_both_servers(run_comparisons): |
| 50 | + result, requests = run_comparisons() |
| 51 | + assert result.returncode == 0, result.stderr |
| 52 | + assert len(requests) == 14 |
| 53 | + expected = [ |
| 54 | + {"strategy": "fast"}, |
| 55 | + {"strategy": "auto"}, |
| 56 | + {"strategy": "hi_res"}, |
| 57 | + {"strategy": "fast", "coordinates": "true"}, |
| 58 | + {"strategy": "fast", "encoding": "utf-8"}, |
| 59 | + {"strategy": "fast", "include_page_breaks": "true"}, |
| 60 | + {"strategy": "hi_res", "hi_res_model_name": "yolox"}, |
| 61 | + ] |
| 62 | + for index, args in enumerate(requests): |
| 63 | + fields = dict(args[i + 1].split("=", 1) for i, arg in enumerate(args) if arg == "-F") |
| 64 | + assert fields.pop("files") == "@sample-docs/layout-parser-paper.pdf" |
| 65 | + assert fields == expected[index // 2] |
| 66 | + server = "single" if index % 2 == 0 else "parallel" |
| 67 | + assert f"http://{server}/general/v0/general" in args |
| 68 | + assert "--fail" in args |
| 69 | + |
| 70 | + |
| 71 | +@pytest.mark.parametrize("body", ['{"detail": "server error"}', "[]", "invalid JSON"]) |
| 72 | +def test_comparisons_reject_invalid_responses(run_comparisons, body): |
| 73 | + result, requests = run_comparisons(RESPONSE_BODY=body) |
| 74 | + assert result.returncode != 0 |
| 75 | + assert len(requests) == 1 |
| 76 | + |
| 77 | + |
| 78 | +def test_comparisons_reject_http_failure(run_comparisons): |
| 79 | + result, requests = run_comparisons(HTTP_FAILURE="1") |
| 80 | + assert result.returncode != 0 |
| 81 | + assert len(requests) == 1 |
| 82 | + |
| 83 | + |
| 84 | +def test_comparisons_reject_different_element_counts(run_comparisons): |
| 85 | + result, requests = run_comparisons(MISMATCH="1") |
| 86 | + assert result.returncode != 0 |
| 87 | + assert len(requests) == 2 |
| 88 | + assert "different number of elements" in result.stdout |
0 commit comments