Download test/test_log_service.py from zlcy/study: direct link, hf CLI and curl.
- Browser
- Download file 4.98 kB
-
https://huggingface.co/spaces/zlcy/study/resolve/main/test/test_log_service.py
- Command line
-
hf download hf://spaces/zlcy/study/test/test_log_service.py
-
curl -L -o test_log_service.py https://huggingface.co/spaces/zlcy/study/resolve/main/test/test_log_service.py
4.98 kB
| from __future__ import annotations | |
| import json | |
| import os | |
| import tempfile | |
| import unittest | |
| from pathlib import Path | |
| from unittest import mock | |
| from fastapi import HTTPException | |
| from services.log_service import LogService, LoggedCall | |
| class LogServiceTests(unittest.TestCase): | |
| def setUp(self): | |
| self.tmp = tempfile.TemporaryDirectory() | |
| self.addCleanup(self.tmp.cleanup) | |
| self.path = Path(self.tmp.name) / "logs.jsonl" | |
| def write_logs(self, count: int = 5) -> None: | |
| rows = [] | |
| for index in range(count): | |
| rows.append(json.dumps({ | |
| "id": f"log-{index}", | |
| "time": f"2026-08-0{index + 1} 12:00:00", | |
| "type": "call" if index % 2 == 0 else "account", | |
| "summary": f"item {index}", | |
| }, ensure_ascii=False)) | |
| self.path.write_text("\n".join(rows) + "\n", encoding="utf-8") | |
| def test_list_reads_newest_lines_without_reading_whole_file(self): | |
| self.write_logs(5) | |
| service = LogService(self.path) | |
| with mock.patch.object(Path, "read_text", side_effect=AssertionError("read_text should not be used by list")): | |
| items = service.list(limit=2) | |
| self.assertEqual([item["id"] for item in items], ["log-4", "log-3"]) | |
| def test_list_applies_filters_while_reading_backwards(self): | |
| self.write_logs(5) | |
| items = LogService(self.path).list(type="call", start_date="2026-08-03", limit=10) | |
| self.assertEqual([item["id"] for item in items], ["log-4", "log-2"]) | |
| def test_list_legacy_ids_can_be_deleted(self): | |
| self.path.write_text( | |
| "\n".join([ | |
| json.dumps({"time": "2026-08-01 12:00:00", "type": "call", "summary": "old"}), | |
| json.dumps({"time": "2026-08-02 12:00:00", "type": "call", "summary": "new"}), | |
| ]) + "\n", | |
| encoding="utf-8", | |
| ) | |
| service = LogService(self.path) | |
| with mock.patch.object(Path, "read_text", side_effect=AssertionError("read_text should not be used by list/delete")): | |
| newest = service.list(limit=1)[0] | |
| result = service.delete([newest["id"]]) | |
| remaining = service.list(limit=10) | |
| self.assertEqual(result["removed"], 1) | |
| self.assertEqual([item["summary"] for item in remaining], ["old"]) | |
| def test_add_rotates_oversized_current_log(self): | |
| service = LogService(self.path) | |
| with mock.patch.dict(os.environ, {"CHATGPT2API_LOG_MAX_BYTES": "1"}): | |
| service.add("call", "oversized", {"payload": "x"}) | |
| archives = list(self.path.parent.glob("logs-*.jsonl")) | |
| self.assertEqual(len(archives), 1) | |
| self.assertEqual(self.path.read_text(encoding="utf-8"), "") | |
| self.assertIn("oversized", archives[0].read_text(encoding="utf-8")) | |
| def test_add_rotates_existing_oversized_log_before_writing_new_item(self): | |
| self.path.write_text("x" * 600, encoding="utf-8") | |
| service = LogService(self.path) | |
| with mock.patch.dict(os.environ, {"CHATGPT2API_LOG_MAX_BYTES": "512"}): | |
| service.add("call", "fresh", {"payload": "x"}) | |
| archives = list(self.path.parent.glob("logs-*.jsonl")) | |
| self.assertEqual(len(archives), 1) | |
| self.assertEqual(archives[0].read_text(encoding="utf-8"), "x" * 600) | |
| self.assertIn("fresh", self.path.read_text(encoding="utf-8")) | |
| def test_delete_refuses_to_rewrite_oversized_log(self): | |
| self.write_logs(5) | |
| service = LogService(self.path) | |
| newest = service.list(limit=1)[0] | |
| with mock.patch.dict(os.environ, {"CHATGPT2API_LOG_DELETE_REWRITE_MAX_BYTES": "1"}): | |
| with self.assertRaises(HTTPException) as raised: | |
| service.delete([newest["id"]]) | |
| self.assertEqual(raised.exception.status_code, 413) | |
| def test_stream_hides_account_email_but_admin_log_keeps_it(self): | |
| email = "stream-pool@example.com" | |
| captured_logs: list[dict[str, object]] = [] | |
| def capture_log(_type, _summary="", detail=None, **_data): | |
| captured_logs.append(dict(detail or {})) | |
| call = LoggedCall( | |
| identity={"id": "normal-1", "name": "Normal", "role": "normal"}, | |
| endpoint="/v1/chat/completions", | |
| model="gpt-image-2", | |
| summary="stream", | |
| ) | |
| chunks = [ | |
| { | |
| "delta": "done", | |
| "account_email": email, | |
| "_account_email": email, | |
| "_conversation_id": "conversation-1", | |
| } | |
| ] | |
| with mock.patch("services.log_service.log_service.add", capture_log): | |
| public_chunks = list(call.stream(chunks)) | |
| self.assertEqual(public_chunks, [{"delta": "done", "_conversation_id": "conversation-1"}]) | |
| self.assertTrue( | |
| any(item.get("account_email") == email for item in captured_logs), | |
| captured_logs, | |
| ) | |
| if __name__ == "__main__": | |
| unittest.main() | |