Skip to content

Commit 0220f57

Browse files
authored
chore: Add test cases for file storage (#82)
Signed-off-by: Ce Gao <cegao@tensorchord.ai>
1 parent b5c15ac commit 0220f57

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

requirements-test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pytest
2+
pytest-asyncio

src/tests/test_file_storage.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import asyncio
2+
import os
3+
import shutil
4+
5+
import pytest
6+
7+
from vllm_router.files import FileStorage, OpenAIFile
8+
9+
TEST_BASE_PATH = "/tmp/test_vllm_files"
10+
pytest_plugins = ("pytest_asyncio",)
11+
12+
13+
@pytest.fixture(autouse=True)
14+
async def cleanup():
15+
"""Cleanup test files after each test"""
16+
print("Cleaning up test files")
17+
if os.path.exists(TEST_BASE_PATH):
18+
await asyncio.to_thread(shutil.rmtree, TEST_BASE_PATH)
19+
yield
20+
print("Cleaning up test files")
21+
if os.path.exists(TEST_BASE_PATH):
22+
await asyncio.to_thread(shutil.rmtree, TEST_BASE_PATH)
23+
24+
25+
@pytest.fixture
26+
def storage():
27+
"""Create a FileStorage instance for testing"""
28+
return FileStorage(TEST_BASE_PATH)
29+
30+
31+
@pytest.mark.asyncio
32+
async def test_save_and_get_file(storage):
33+
"""Test basic file save and retrieval operations"""
34+
test_content = b"Hello, World!"
35+
test_filename = "test.txt"
36+
37+
# Save file
38+
saved_file = await storage.save_file(
39+
file_name=test_filename, content=test_content, purpose="test"
40+
)
41+
42+
assert isinstance(saved_file, OpenAIFile)
43+
assert saved_file.filename == test_filename
44+
assert saved_file.bytes == len(test_content)
45+
assert saved_file.purpose == "test"
46+
47+
# Get file metadata
48+
retrieved_file = await storage.get_file(saved_file.id)
49+
assert isinstance(retrieved_file, OpenAIFile)
50+
assert retrieved_file.id == saved_file.id
51+
# File name is not stored in metadata yet.
52+
# assert retrieved_file.filename == test_filename
53+
assert retrieved_file.bytes == len(test_content)
54+
55+
# Get file content
56+
content = await storage.get_file_content(saved_file.id)
57+
assert content == test_content
58+
59+
60+
@pytest.mark.asyncio
61+
async def test_list_files(storage):
62+
"""Test listing files"""
63+
# I am not sure why this is necessary. The cleanup fixture should
64+
# take care of this. But the test fails without this line.
65+
shutil.rmtree(TEST_BASE_PATH)
66+
67+
# Save multiple files
68+
files = []
69+
for i in range(3):
70+
file = await storage.save_file(
71+
file_name=f"test{i}.txt",
72+
content=f"content{i}".encode(),
73+
)
74+
files.append(file)
75+
76+
# List files
77+
file_list = await storage.list_files()
78+
assert len(file_list) == 3
79+
for file in files:
80+
assert file.id in file_list
81+
82+
83+
@pytest.mark.asyncio
84+
async def test_delete_file(storage):
85+
"""Test file deletion"""
86+
# Save a file
87+
saved_file = await storage.save_file(
88+
file_name="test.txt",
89+
content=b"test content",
90+
)
91+
92+
# Verify file exists
93+
files = await storage.list_files()
94+
assert saved_file.id in files
95+
96+
# Delete file
97+
await storage.delete_file(saved_file.id)
98+
99+
# Verify file is deleted
100+
files = await storage.list_files()
101+
assert saved_file.id not in files
102+
103+
# Try to get deleted file
104+
with pytest.raises(FileNotFoundError):
105+
await storage.get_file(saved_file.id)
106+
107+
108+
@pytest.mark.asyncio
109+
async def test_save_file_with_explicit_id(storage):
110+
"""Test saving a file with an explicit ID"""
111+
explicit_id = "custom-id-123"
112+
content = b"test content"
113+
114+
saved_file = await storage.save_file(
115+
file_id=explicit_id,
116+
file_name="test.txt",
117+
content=content,
118+
)
119+
120+
assert saved_file.id == explicit_id
121+
retrieved_content = await storage.get_file_content(explicit_id)
122+
assert retrieved_content == content
123+
124+
125+
# TODO(gaocegege): Add test for saving file chunk
126+
127+
128+
@pytest.mark.asyncio
129+
async def test_error_conditions(storage):
130+
"""Test various error conditions"""
131+
# Test saving file with no content
132+
with pytest.raises(ValueError):
133+
await storage.save_file(file_name="test.txt")
134+
135+
# Test getting non-existent file
136+
with pytest.raises(FileNotFoundError):
137+
await storage.get_file("nonexistent-file")
138+
139+
# Test getting content of non-existent file
140+
with pytest.raises(FileNotFoundError):
141+
await storage.get_file_content("nonexistent-file")

0 commit comments

Comments
 (0)