"""Tests for shared.secrets caching.""" from unittest.mock import MagicMock, patch def test_get_parameter_refetches_after_ttl(): """SSM parameter values expire so callers can observe rotations.""" from shared import secrets secrets._secret_cache.clear() secrets._parameter_cache.clear() mock_ssm = MagicMock() mock_ssm.get_parameter.side_effect = [ {"Parameter": {"Value": "first"}}, {"Parameter": {"Value": "second"}}, ] with patch.object(secrets, "_ssm", mock_ssm): with patch.object(secrets, "PARAM_CACHE_TTL_SECONDS", 10.0): with patch( "shared.secrets.time.monotonic", side_effect=[0.0, 5.0, 15.0], ): assert secrets.get_parameter("/test/param") == "first" assert secrets.get_parameter("/test/param") == "first" assert secrets.get_parameter("/test/param") == "second" assert mock_ssm.get_parameter.call_count == 2 def test_get_secret_stays_cached(): """Secrets Manager values remain cached (no TTL).""" from shared import secrets secrets._secret_cache.clear() secrets._parameter_cache.clear() mock_sm = MagicMock() mock_sm.get_secret_value.side_effect = [ {"SecretString": "a"}, {"SecretString": "b"}, ] with patch.object(secrets, "_sm", mock_sm): with patch("shared.secrets.time.monotonic", side_effect=[0.0, 5000.0]): assert secrets.get_secret("arn:aws:secret") == "a" assert secrets.get_secret("arn:aws:secret") == "a" assert mock_sm.get_secret_value.call_count == 1