Spaces:
				
			
			
	
			
			
		Sleeping
		
	
	
	
			
			
	
	
	
	
		
		
		Sleeping
		
	| #!/usr/bin/env python3 | |
| """ | |
| Lily LLM API ์ข ํฉ ํ ์คํธ ์ค์ํธ | |
| ๋ชจ๋ ์ฃผ์ ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ํตํฉ ํ ์คํธ | |
| """ | |
| import pytest | |
| import requests | |
| import time | |
| import json | |
| import os | |
| import tempfile | |
| from pathlib import Path | |
| # ํ ์คํธ ์ค์  | |
| BASE_URL = "http://localhost:8001" | |
| TEST_USER_ID = "test_user_123" | |
| TEST_SESSION_ID = "test_session_123" | |
| class TestLilyLLMAPI: | |
| """Lily LLM API ์ข ํฉ ํ ์คํธ ํด๋์ค""" | |
| def setup_method(self): | |
| """๊ฐ ํ ์คํธ ์  ์คํ""" | |
| self.session = requests.Session() | |
| self.token = None | |
| def teardown_method(self): | |
| """๊ฐ ํ ์คํธ ํ ์คํ""" | |
| self.session.close() | |
| def test_01_server_health(self): | |
| """์๋ฒ ์ํ ํ์ธ""" | |
| response = self.session.get(f"{BASE_URL}/health") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "status" in data | |
| assert "current_model" in data | |
| print("โ ์๋ฒ ์ํ ํ์ธ ์ฑ๊ณต") | |
| def test_02_models_endpoint(self): | |
| """๋ชจ๋ธ ๋ชฉ๋ก ์กฐํ""" | |
| response = self.session.get(f"{BASE_URL}/models") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "available_models" in data | |
| assert len(data["available_models"]) > 0 | |
| print("โ ๋ชจ๋ธ ๋ชฉ๋ก ์กฐํ ์ฑ๊ณต") | |
| def test_03_text_generation(self): | |
| """ํ ์คํธ ์์ฑ ํ ์คํธ""" | |
| data = { | |
| "prompt": "์๋ ํ์ธ์! ๊ฐ๋จํ ์ธ์ฌ๋ง์ ํด์ฃผ์ธ์.", | |
| "model_id": "polyglot-ko-1.3b-chat", | |
| "max_length": 100, | |
| "temperature": 0.7, | |
| "top_p": 0.9, | |
| "do_sample": True | |
| } | |
| response = self.session.post(f"{BASE_URL}/generate", data=data) | |
| assert response.status_code == 200 | |
| result = response.json() | |
| assert "generated_text" in result | |
| assert len(result["generated_text"]) > 0 | |
| print("โ ํ ์คํธ ์์ฑ ์ฑ๊ณต") | |
| def test_04_user_management(self): | |
| """์ฌ์ฉ์ ๊ด๋ฆฌ ํ ์คํธ""" | |
| # ์ฌ์ฉ์ ์์ฑ | |
| user_data = { | |
| "user_id": TEST_USER_ID, | |
| "username": "ํ ์คํธ์ฌ์ฉ์", | |
| "email": "test@example.com" | |
| } | |
| response = self.session.post(f"{BASE_URL}/user/create", data=user_data) | |
| assert response.status_code == 200 | |
| print("โ ์ฌ์ฉ์ ์์ฑ ์ฑ๊ณต") | |
| # ์ฌ์ฉ์ ์ ๋ณด ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/user/{TEST_USER_ID}") | |
| assert response.status_code == 200 | |
| user_info = response.json() | |
| assert user_info["user_id"] == TEST_USER_ID | |
| print("โ ์ฌ์ฉ์ ์ ๋ณด ์กฐํ ์ฑ๊ณต") | |
| def test_05_authentication(self): | |
| """์ธ์ฆ ์์คํ  ํ ์คํธ""" | |
| # ์ฌ์ฉ์ ๋ฑ๋ก | |
| register_data = { | |
| "username": "testuser", | |
| "email": "test@example.com", | |
| "password": "testpassword123" | |
| } | |
| response = self.session.post(f"{BASE_URL}/auth/register", data=register_data) | |
| assert response.status_code == 200 | |
| register_result = response.json() | |
| assert "access_token" in register_result | |
| self.token = register_result["access_token"] | |
| print("โ ์ฌ์ฉ์ ๋ฑ๋ก ์ฑ๊ณต") | |
| # ๋ก๊ทธ์ธ | |
| login_data = { | |
| "username": "testuser", | |
| "password": "testpassword123" | |
| } | |
| response = self.session.post(f"{BASE_URL}/auth/login", data=login_data) | |
| assert response.status_code == 200 | |
| login_result = response.json() | |
| assert "access_token" in login_result | |
| print("โ ๋ก๊ทธ์ธ ์ฑ๊ณต") | |
| # ํ์ฌ ์ฌ์ฉ์ ์ ๋ณด ์กฐํ | |
| headers = {"Authorization": f"Bearer {self.token}"} | |
| response = self.session.get(f"{BASE_URL}/auth/me", headers=headers) | |
| assert response.status_code == 200 | |
| print("โ ํ์ฌ ์ฌ์ฉ์ ์ ๋ณด ์กฐํ ์ฑ๊ณต") | |
| def test_06_chat_session_management(self): | |
| """์ฑํ ์ธ์  ๊ด๋ฆฌ ํ ์คํธ""" | |
| # ์ธ์  ์์ฑ | |
| session_data = { | |
| "user_id": TEST_USER_ID, | |
| "session_name": "ํ ์คํธ ์ธ์ " | |
| } | |
| response = self.session.post(f"{BASE_URL}/session/create", data=session_data) | |
| assert response.status_code == 200 | |
| session_result = response.json() | |
| session_id = session_result["session_id"] | |
| print("โ ์ธ์  ์์ฑ ์ฑ๊ณต") | |
| # ๋ฉ์์ง ์ถ๊ฐ | |
| message_data = { | |
| "session_id": session_id, | |
| "user_id": TEST_USER_ID, | |
| "message_type": "text", | |
| "content": "์๋ ํ์ธ์! ํ ์คํธ ๋ฉ์์ง์ ๋๋ค." | |
| } | |
| response = self.session.post(f"{BASE_URL}/chat/message", data=message_data) | |
| assert response.status_code == 200 | |
| print("โ ๋ฉ์์ง ์ถ๊ฐ ์ฑ๊ณต") | |
| # ์ฑํ ๊ธฐ๋ก ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/chat/history/{session_id}") | |
| assert response.status_code == 200 | |
| history = response.json() | |
| assert len(history) > 0 | |
| print("โ ์ฑํ ๊ธฐ๋ก ์กฐํ ์ฑ๊ณต") | |
| def test_07_document_upload(self): | |
| """๋ฌธ์ ์ ๋ก๋ ํ ์คํธ""" | |
| # ์์ PDF ํ์ผ ์์ฑ | |
| with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp_file: | |
| tmp_file.write(b"%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n2 0 obj\n<<\n/Type /Pages\n/Kids [3 0 R]\n/Count 1\n>>\nendobj\n3 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/MediaBox [0 0 612 792]\n/Contents 4 0 R\n>>\nendobj\n4 0 obj\n<<\n/Length 44\n>>\nstream\nBT\n/F1 12 Tf\n72 720 Td\n(Test PDF) Tj\nET\nendstream\nendobj\nxref\n0 5\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \n0000000204 00000 n \ntrailer\n<<\n/Size 5\n/Root 1 0 R\n>>\nstartxref\n297\n%%EOF\n") | |
| tmp_file_path = tmp_file.name | |
| try: | |
| with open(tmp_file_path, 'rb') as f: | |
| files = {'file': f} | |
| data = {'user_id': TEST_USER_ID} | |
| response = self.session.post(f"{BASE_URL}/document/upload", files=files, data=data) | |
| assert response.status_code == 200 | |
| upload_result = response.json() | |
| assert "document_id" in upload_result | |
| print("โ ๋ฌธ์ ์ ๋ก๋ ์ฑ๊ณต") | |
| # ์ฌ์ฉ์ ๋ฌธ์ ๋ชฉ๋ก ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/documents/db/{TEST_USER_ID}") | |
| assert response.status_code == 200 | |
| documents = response.json() | |
| assert len(documents) > 0 | |
| print("โ ๋ฌธ์ ๋ชฉ๋ก ์กฐํ ์ฑ๊ณต") | |
| finally: | |
| os.unlink(tmp_file_path) | |
| def test_08_rag_functionality(self): | |
| """RAG ๊ธฐ๋ฅ ํ ์คํธ""" | |
| # RAG ์ฟผ๋ฆฌ | |
| rag_data = { | |
| "query": "ํ ์คํธ ์ฟผ๋ฆฌ์ ๋๋ค.", | |
| "user_id": TEST_USER_ID, | |
| "max_length": 200, | |
| "temperature": 0.7 | |
| } | |
| response = self.session.post(f"{BASE_URL}/rag/generate", data=rag_data) | |
| assert response.status_code == 200 | |
| rag_result = response.json() | |
| assert "response" in rag_result | |
| print("โ RAG ์ฟผ๋ฆฌ ์ฑ๊ณต") | |
| def test_09_background_tasks(self): | |
| """๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ํ ์คํธ""" | |
| # ๋ฌธ์ ์ฒ๋ฆฌ ์์ ์์ | |
| task_data = { | |
| "file_path": "/tmp/test_document.pdf", | |
| "user_id": TEST_USER_ID | |
| } | |
| response = self.session.post(f"{BASE_URL}/tasks/document/process", data=task_data) | |
| assert response.status_code == 200 | |
| task_result = response.json() | |
| assert "task_id" in task_result | |
| task_id = task_result["task_id"] | |
| print("โ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์์ ์ฑ๊ณต") | |
| # ์์ ์ํ ํ์ธ | |
| response = self.session.get(f"{BASE_URL}/tasks/{task_id}") | |
| assert response.status_code == 200 | |
| status_result = response.json() | |
| assert "status" in status_result | |
| print("โ ์์ ์ํ ํ์ธ ์ฑ๊ณต") | |
| def test_10_monitoring(self): | |
| """๋ชจ๋ํฐ๋ง ๊ธฐ๋ฅ ํ ์คํธ""" | |
| # ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ์์ | |
| response = self.session.post(f"{BASE_URL}/monitoring/start") | |
| assert response.status_code == 200 | |
| print("โ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ์์ ์ฑ๊ณต") | |
| # ๋ชจ๋ํฐ๋ง ์ํ ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/monitoring/status") | |
| assert response.status_code == 200 | |
| status_data = response.json() | |
| assert "current_metrics" in status_data | |
| print("โ ๋ชจ๋ํฐ๋ง ์ํ ์กฐํ ์ฑ๊ณต") | |
| # ์์คํ  ๊ฑด๊ฐ ์ํ ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/monitoring/health") | |
| assert response.status_code == 200 | |
| health_data = response.json() | |
| assert "status" in health_data | |
| print("โ ์์คํ  ๊ฑด๊ฐ ์ํ ์กฐํ ์ฑ๊ณต") | |
| # ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ์ค์ง | |
| response = self.session.post(f"{BASE_URL}/monitoring/stop") | |
| assert response.status_code == 200 | |
| print("โ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ์ค์ง ์ฑ๊ณต") | |
| def test_11_websocket_connection(self): | |
| """WebSocket ์ฐ๊ฒฐ ํ ์คํธ""" | |
| try: | |
| import websockets | |
| import asyncio | |
| async def test_websocket(): | |
| uri = f"ws://localhost:8001/ws/{TEST_USER_ID}" | |
| async with websockets.connect(uri) as websocket: | |
| # ์ฐ๊ฒฐ ํ ์คํธ | |
| await websocket.send(json.dumps({ | |
| "type": "ping", | |
| "message": "ํ ์คํธ ๋ฉ์์ง" | |
| })) | |
| # ์๋ต ๋๊ธฐ | |
| response = await asyncio.wait_for(websocket.recv(), timeout=5.0) | |
| data = json.loads(response) | |
| assert "type" in data | |
| print("โ WebSocket ์ฐ๊ฒฐ ์ฑ๊ณต") | |
| asyncio.run(test_websocket()) | |
| except ImportError: | |
| print("โ ๏ธ websockets ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ค์น๋์ง ์์ WebSocket ํ ์คํธ๋ฅผ ๊ฑด๋๋๋๋ค.") | |
| except Exception as e: | |
| print(f"โ ๏ธ WebSocket ํ ์คํธ ์คํจ: {e}") | |
| def test_12_error_handling(self): | |
| """์ค๋ฅ ์ฒ๋ฆฌ ํ ์คํธ""" | |
| # ์๋ชป๋ ๋ชจ๋ธ ID๋ก ์์ฒญ | |
| data = { | |
| "prompt": "ํ ์คํธ", | |
| "model_id": "invalid-model-id", | |
| "max_length": 100 | |
| } | |
| response = self.session.post(f"{BASE_URL}/generate", data=data) | |
| assert response.status_code in [400, 404, 422] | |
| print("โ ์๋ชป๋ ๋ชจ๋ธ ID ์ค๋ฅ ์ฒ๋ฆฌ ์ฑ๊ณต") | |
| # ์๋ชป๋ ์ฌ์ฉ์ ID๋ก ์์ฒญ | |
| response = self.session.get(f"{BASE_URL}/user/invalid-user-id") | |
| assert response.status_code in [404, 422] | |
| print("โ ์๋ชป๋ ์ฌ์ฉ์ ID ์ค๋ฅ ์ฒ๋ฆฌ ์ฑ๊ณต") | |
| def test_13_performance_metrics(self): | |
| """์ฑ๋ฅ ๋ฉํธ๋ฆญ ํ ์คํธ""" | |
| # ์ฌ๋ฌ ์์ฒญ์ ๋ณด๋ด์ ์ฑ๋ฅ ์ธก์  | |
| start_time = time.time() | |
| for i in range(5): | |
| data = { | |
| "prompt": f"ํ ์คํธ ์์ฒญ {i+1}", | |
| "model_id": "polyglot-ko-1.3b-chat", | |
| "max_length": 50, | |
| "temperature": 0.7 | |
| } | |
| response = self.session.post(f"{BASE_URL}/generate", data=data) | |
| assert response.status_code == 200 | |
| end_time = time.time() | |
| total_time = end_time - start_time | |
| print(f"โ ์ฑ๋ฅ ํ ์คํธ ์๋ฃ: 5๊ฐ ์์ฒญ์ {total_time:.2f}์ด์ ์ฒ๋ฆฌ") | |
| assert total_time < 60 # 60์ด ์ด๋ด์ ์๋ฃ๋์ด์ผ ํจ | |
| def test_14_data_persistence(self): | |
| """๋ฐ์ดํฐ ์ง์์ฑ ํ ์คํธ""" | |
| # ์ฌ์ฉ์ ์์ฑ | |
| user_data = { | |
| "user_id": f"persist_test_user_{int(time.time())}", | |
| "username": "์ง์์ฑํ ์คํธ์ฌ์ฉ์", | |
| "email": "persist@test.com" | |
| } | |
| response = self.session.post(f"{BASE_URL}/user/create", data=user_data) | |
| assert response.status_code == 200 | |
| user_id = user_data["user_id"] | |
| # ์๋ฒ ์ฌ์์ ์๋ฎฌ๋ ์ด์  (์ค์ ๋ก๋ ์ฌ์์ํ์ง ์์) | |
| # ๋์ ๋์ผํ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ค์ ์กฐํ | |
| response = self.session.get(f"{BASE_URL}/user/{user_id}") | |
| assert response.status_code == 200 | |
| user_info = response.json() | |
| assert user_info["user_id"] == user_id | |
| print("โ ๋ฐ์ดํฐ ์ง์์ฑ ํ์ธ ์ฑ๊ณต") | |
| def run_comprehensive_test(): | |
| """์ข ํฉ ํ ์คํธ ์คํ""" | |
| print("๐ Lily LLM API ์ข ํฉ ํ ์คํธ ์์") | |
| print("=" * 60) | |
| test_instance = TestLilyLLMAPI() | |
| # ํ ์คํธ ๋ฉ์๋ ๋ชฉ๋ก | |
| test_methods = [ | |
| test_instance.test_01_server_health, | |
| test_instance.test_02_models_endpoint, | |
| test_instance.test_03_text_generation, | |
| test_instance.test_04_user_management, | |
| test_instance.test_05_authentication, | |
| test_instance.test_06_chat_session_management, | |
| test_instance.test_07_document_upload, | |
| test_instance.test_08_rag_functionality, | |
| test_instance.test_09_background_tasks, | |
| test_instance.test_10_monitoring, | |
| test_instance.test_11_websocket_connection, | |
| test_instance.test_12_error_handling, | |
| test_instance.test_13_performance_metrics, | |
| test_instance.test_14_data_persistence | |
| ] | |
| passed_tests = 0 | |
| failed_tests = 0 | |
| for i, test_method in enumerate(test_methods, 1): | |
| try: | |
| print(f"\n๐ ํ ์คํธ {i}/{len(test_methods)}: {test_method.__name__}") | |
| print("-" * 50) | |
| test_method() | |
| passed_tests += 1 | |
| except Exception as e: | |
| print(f"โ ํ ์คํธ ์คํจ: {e}") | |
| failed_tests += 1 | |
| # ๊ฒฐ๊ณผ ์์ฝ | |
| print("\n" + "=" * 60) | |
| print("๐ ํ ์คํธ ๊ฒฐ๊ณผ ์์ฝ") | |
| print("=" * 60) | |
| print(f"โ ํต๊ณผ: {passed_tests}") | |
| print(f"โ ์คํจ: {failed_tests}") | |
| print(f"๐ ์ฑ๊ณต๋ฅ : {passed_tests/(passed_tests+failed_tests)*100:.1f}%") | |
| if failed_tests == 0: | |
| print("\n๐ ๋ชจ๋ ํ ์คํธ๊ฐ ์ฑ๊ณตํ์ต๋๋ค!") | |
| return True | |
| else: | |
| print(f"\nโ ๏ธ {failed_tests}๊ฐ์ ํ ์คํธ๊ฐ ์คํจํ์ต๋๋ค.") | |
| return False | |
| if __name__ == "__main__": | |
| success = run_comprehensive_test() | |
| exit(0 if success else 1) |