odysseusphone / tests /test_api_key_manager_atomic_save.py
Earring9405's picture
Upload folder using huggingface_hub (part 2)
b594234 verified
Raw
History Blame Contribute Delete
2.67 kB
"""Test that APIKeyManager.save() uses atomic write to prevent data loss."""
import os
import json
import pytest
from unittest.mock import patch, mock_open
from src.api_key_manager import APIKeyManager
def test_save_creates_atomic_tmp_file(tmp_path):
"""Verify save() writes to a temp file and replaces atomically."""
mgr = APIKeyManager(str(tmp_path))
mgr.save("openai", "sk-test")
# The final file should exist with the correct content
assert os.path.exists(mgr.api_keys_file)
with open(mgr.api_keys_file, "r", encoding="utf-8") as f:
keys = json.load(f)
assert "openai" in keys
# The temp file should NOT remain after successful save
tmp_file = mgr.api_keys_file + ".tmp"
assert not os.path.exists(tmp_file)
def test_save_preserves_existing_keys_atomically(tmp_path):
"""Verify atomic save doesn't corrupt other providers' keys."""
mgr = APIKeyManager(str(tmp_path))
mgr.save("openai", "sk-openai")
mgr.save("anthropic", "sk-anthropic")
loaded = mgr.load()
assert loaded["openai"] == "sk-openai"
assert loaded["anthropic"] == "sk-anthropic"
def test_save_preserves_original_on_write_failure(tmp_path):
"""If the temp file write fails, the original keys file must survive intact."""
mgr = APIKeyManager(str(tmp_path))
mgr.save("openai", "sk-original")
# Now attempt a save that will fail during json.dump
with patch("builtins.open", side_effect=OSError("disk full")):
with pytest.raises(OSError, match="disk full"):
mgr.save("anthropic", "sk-new")
# Original file must still be intact with the original key
loaded = mgr.load()
assert loaded == {"openai": "sk-original"}
assert "anthropic" not in loaded
def test_save_cleans_up_tmp_on_failure(tmp_path):
"""Temp file should be removed if the write fails."""
mgr = APIKeyManager(str(tmp_path))
mgr.save("openai", "sk-original")
tmp_file = mgr.api_keys_file + ".tmp"
# Force a failure after the temp file is opened
original_open = open
def failing_open(*args, **kwargs):
f = original_open(*args, **kwargs)
if args and isinstance(args[0], str) and args[0].endswith(".tmp"):
# Close the file then raise
f.close()
raise OSError("simulated write failure")
return f
with patch("builtins.open", side_effect=failing_open):
with pytest.raises(OSError):
mgr.save("anthropic", "sk-new")
# Temp file should be cleaned up
assert not os.path.exists(tmp_file)
# Original should be intact
loaded = mgr.load()
assert loaded == {"openai": "sk-original"}