"""
Test Cache Control for CloudWatch Optimization
Demonstrates how to control caching behavior for testing purposes.
"""
import pytest
import os
from utils.cache_decorator import (
dao_cache,
is_cache_enabled,
enable_cache,
disable_cache,
clear_cache,
get_cache_stats
)
class TestCacheControl:
"""Test cache control functionality."""
def test_cache_enabled_by_default(self):
"""Test that cache is enabled by default."""
# Cache should be enabled by default (unless CFM_ENABLE_CACHE=false)
assert is_cache_enabled() in (True, False) # Depends on environment
def test_disable_cache_programmatically(self):
"""Test disabling cache programmatically."""
# Save original state
original_state = is_cache_enabled()
try:
# Disable cache
disable_cache()
assert is_cache_enabled() is False
# Enable cache
enable_cache()
assert is_cache_enabled() is True
finally:
# Restore original state
if original_state:
enable_cache()
else:
disable_cache()
def test_cache_decorator_respects_global_setting(self):
"""Test that decorator respects global cache setting."""
call_count = 0
@dao_cache(ttl_seconds=60)
def test_function(value):
nonlocal call_count
call_count += 1
return value * 2
# Save original state
original_state = is_cache_enabled()
try:
# Test with cache enabled
enable_cache()
clear_cache()
call_count = 0
result1 = test_function(5)
result2 = test_function(5)
assert result1 == 10
assert result2 == 10
assert call_count == 1 # Should only call once due to caching
# Test with cache disabled
disable_cache()
clear_cache()
call_count = 0
result1 = test_function(5)
result2 = test_function(5)
assert result1 == 10
assert result2 == 10
assert call_count == 2 # Should call twice without caching
finally:
# Restore original state
if original_state:
enable_cache()
else:
disable_cache()
def test_cache_decorator_with_enabled_parameter(self):
"""Test that decorator enabled parameter overrides global setting."""
call_count = 0
@dao_cache(ttl_seconds=60, enabled=False)
def always_uncached(value):
nonlocal call_count
call_count += 1
return value * 2
# Save original state
original_state = is_cache_enabled()
try:
# Even with cache enabled globally, this function should not cache
enable_cache()
clear_cache()
call_count = 0
result1 = always_uncached(5)
result2 = always_uncached(5)
assert result1 == 10
assert result2 == 10
assert call_count == 2 # Should call twice (caching disabled)
finally:
# Restore original state
if original_state:
enable_cache()
else:
disable_cache()
def test_cache_stats(self):
"""Test cache statistics.
NOTE: This test uses 'page' parameter which is in the important_params list
of _generate_cache_key(). Using other parameters may not generate unique
cache keys due to the selective parameter inclusion in the cache decorator.
"""
# Save original state
original_state = is_cache_enabled()
try:
enable_cache()
clear_cache()
# Define function after clearing cache to ensure clean state
# Use 'page' parameter which is in the cache decorator's important_params list
@dao_cache(ttl_seconds=60)
def test_function(page=1):
return page * 2
# Make some calls using page parameter (which IS in important_params)
result1 = test_function(page=1) # MISS
result2 = test_function(page=1) # HIT
result3 = test_function(page=2) # MISS
result4 = test_function(page=2) # HIT
# Verify results are correct
assert result1 == 2
assert result2 == 2
assert result3 == 4
assert result4 == 4
stats = get_cache_stats()
assert 'hits' in stats
assert 'misses' in stats
assert 'hit_rate' in stats
assert 'enabled' in stats
assert stats['enabled'] is True
# The test expects exactly 2 hits and 2 misses
assert stats['hits'] == 2, f"Expected 2 hits but got {stats['hits']}"
assert stats['misses'] == 2, f"Expected 2 misses but got {stats['misses']}"
finally:
# Restore original state
clear_cache()
if original_state:
enable_cache()
else:
disable_cache()
class TestCacheEnvironmentVariable:
"""Test cache control via environment variable."""
def test_cache_disabled_via_env_var(self, monkeypatch):
"""Test disabling cache via CFM_ENABLE_CACHE environment variable."""
# This test would need to reload the module to test env var
# For now, just document the behavior
pass
# Example usage in tests
@pytest.fixture
def disable_cache_for_test():
"""Fixture to disable cache for a specific test."""
original_state = is_cache_enabled()
disable_cache()
clear_cache()
yield
if original_state:
enable_cache()
else:
disable_cache()
def test_with_cache_disabled(disable_cache_for_test):
"""Example test that runs with cache disabled."""
# Your test code here
# Cache will be disabled for this test
assert is_cache_enabled() is False
@pytest.fixture
def enable_cache_for_test():
"""Fixture to enable cache for a specific test."""
original_state = is_cache_enabled()
enable_cache()
clear_cache()
yield
if original_state:
enable_cache()
else:
disable_cache()
def test_with_cache_enabled(enable_cache_for_test):
"""Example test that runs with cache enabled."""
# Your test code here
# Cache will be enabled for this test
assert is_cache_enabled() is True