Skip to content

Commit 89d6f28

Browse files
committed
redis test passing
1 parent 870e8e2 commit 89d6f28

File tree

3 files changed

+276
-0
lines changed

3 files changed

+276
-0
lines changed

backend/apps/credits/tasks.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from celery import shared_task
2+
import logging
3+
from datetime import datetime
4+
5+
logger = logging.getLogger('credits')
6+
7+
@shared_task
8+
def cleanup_expired_credit_holds():
9+
"""Task to clean up expired credit holds."""
10+
now = datetime.now()
11+
logger.info(f"[{now}] Running cleanup for expired credit holds")
12+
# In a real implementation, you would add code to find and release expired holds
13+
# For example:
14+
# from apps.credits.models import CreditHold
15+
# expired_holds = CreditHold.objects.filter(expires_at__lt=now, is_active=True)
16+
# count = expired_holds.count()
17+
# for hold in expired_holds:
18+
# hold.release()
19+
# logger.info(f"Released {count} expired credit holds")
20+
21+
# For testing, just log a message
22+
logger.info("Cleanup task completed successfully")
23+
return "Cleanup completed"

backend/core/tests/test_celery.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import os
2+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
3+
4+
import django
5+
django.setup()
6+
7+
from core.celery import debug_task
8+
9+
if __name__ == '__main__':
10+
# Call the debug task synchronously for testing
11+
print("Testing Celery debug task...")
12+
result = debug_task.apply()
13+
print("Task completed!")

backend/test_redis.py

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
import os
2+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
3+
4+
import django
5+
django.setup()
6+
7+
import redis
8+
from django.conf import settings
9+
import time
10+
import logging
11+
from dotenv import load_dotenv
12+
13+
# Load environment variables from .env.local
14+
load_dotenv(os.path.join(os.path.dirname(os.path.dirname(__file__)), '.env.local'))
15+
16+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
17+
logger = logging.getLogger(__name__)
18+
19+
def test_redis_connection():
20+
"""
21+
Test basic Redis connection and operations.
22+
"""
23+
# Use localhost:6379 since the Redis container exposes this port
24+
redis_url = "redis://localhost:6379/0"
25+
logger.info(f"Connecting to Redis at: {redis_url}")
26+
27+
try:
28+
# Connect to Redis with explicit parameters to avoid version issues
29+
r = redis.from_url(redis_url, socket_connect_timeout=5)
30+
31+
# Test connection with ping
32+
ping_response = r.ping()
33+
logger.info(f"Redis ping response: {ping_response}")
34+
35+
# Test basic operations
36+
test_key = "django_redis_test"
37+
test_value = f"Test value at {time.time()}"
38+
39+
# Set a value
40+
r.set(test_key, test_value)
41+
logger.info(f"Set test key: {test_key} = {test_value}")
42+
43+
# Get the value back
44+
retrieved_value = r.get(test_key)
45+
if retrieved_value:
46+
retrieved_value = retrieved_value.decode('utf-8')
47+
logger.info(f"Retrieved test key: {test_key} = {retrieved_value}")
48+
49+
# Verify the value matches
50+
assert retrieved_value == test_value, "Retrieved value doesn't match set value"
51+
52+
# Test expiration
53+
r.setex(f"{test_key}_with_expiry", 5, "This will expire in 5 seconds")
54+
logger.info("Set key with 5-second expiration")
55+
56+
# Check it exists
57+
assert r.exists(f"{test_key}_with_expiry") == 1, "Expiring key doesn't exist"
58+
logger.info("Verified expiring key exists")
59+
60+
# Wait for expiration
61+
logger.info("Waiting for key to expire...")
62+
time.sleep(6)
63+
64+
# Verify it's gone
65+
assert r.exists(f"{test_key}_with_expiry") == 0, "Key should have expired"
66+
logger.info("Verified key has expired as expected")
67+
68+
# Test list operations
69+
list_key = "django_redis_test_list"
70+
r.delete(list_key) # Ensure clean state
71+
72+
# Push items to list
73+
r.lpush(list_key, "item1", "item2", "item3")
74+
logger.info(f"Pushed 3 items to list: {list_key}")
75+
76+
# Get list length
77+
list_len = r.llen(list_key)
78+
logger.info(f"List length: {list_len}")
79+
assert list_len == 3, "List should have 3 items"
80+
81+
# Get all list items
82+
items = r.lrange(list_key, 0, -1)
83+
items = [item.decode('utf-8') for item in items]
84+
logger.info(f"List items: {items}")
85+
86+
# Clean up
87+
r.delete(test_key, list_key)
88+
logger.info("Cleaned up test keys")
89+
90+
logger.info("All Redis tests passed successfully!")
91+
return True
92+
93+
except redis.RedisError as e:
94+
logger.error(f"Redis error: {e}")
95+
return False
96+
except Exception as e:
97+
logger.error(f"Unexpected error: {e}")
98+
return False
99+
100+
def fix_django_cache_settings():
101+
"""
102+
Fix Django cache settings for local testing.
103+
"""
104+
try:
105+
# Check if CACHES is defined in settings
106+
if hasattr(settings, 'CACHES') and 'default' in settings.CACHES:
107+
cache_config = settings.CACHES['default']
108+
109+
# Log the current configuration
110+
logger.info(f"Current Django CACHES setting: {cache_config}")
111+
112+
# Check for HiredisParser issue
113+
if 'OPTIONS' in cache_config and 'PARSER_CLASS' in cache_config['OPTIONS']:
114+
if cache_config['OPTIONS']['PARSER_CLASS'] == 'redis.connection.HiredisParser':
115+
logger.info("Detected HiredisParser configuration which may not be compatible")
116+
117+
# Modify the settings in memory (won't persist)
118+
# Remove the PARSER_CLASS option which is causing issues
119+
if 'PARSER_CLASS' in cache_config['OPTIONS']:
120+
logger.info("Temporarily removing PARSER_CLASS setting for testing")
121+
del cache_config['OPTIONS']['PARSER_CLASS']
122+
123+
# Update the cache location to use localhost
124+
if 'LOCATION' in cache_config:
125+
original_location = cache_config['LOCATION']
126+
if 'redis:6379' in original_location:
127+
new_location = original_location.replace('redis:6379', 'localhost:6379')
128+
logger.info(f"Updating cache location from {original_location} to {new_location}")
129+
cache_config['LOCATION'] = new_location
130+
131+
return True
132+
except Exception as e:
133+
logger.error(f"Error fixing Django cache settings: {e}")
134+
135+
return False
136+
137+
def test_django_cache():
138+
"""
139+
Test Django's cache framework with Redis backend.
140+
"""
141+
# Fix Django cache settings first
142+
fix_django_cache_settings()
143+
144+
try:
145+
# Try to import the cache module
146+
from django.core.cache import cache
147+
logger.info(f"Django cache backend: {cache.__class__.__name__}")
148+
149+
logger.info("Testing Django cache framework")
150+
151+
# Set a cache value
152+
cache_key = "django_cache_test"
153+
cache_value = f"Django cache test at {time.time()}"
154+
155+
try:
156+
cache.set(cache_key, cache_value, timeout=60)
157+
logger.info(f"Set cache key: {cache_key} = {cache_value}")
158+
159+
# Get the cache value
160+
retrieved_value = cache.get(cache_key)
161+
logger.info(f"Retrieved cache key: {cache_key} = {retrieved_value}")
162+
163+
# Verify the value matches
164+
assert retrieved_value == cache_value, "Retrieved cache value doesn't match set value"
165+
166+
# Test cache expiration (with a short timeout)
167+
short_key = "django_cache_short"
168+
cache.set(short_key, "This will expire quickly", timeout=2)
169+
logger.info("Set cache key with 2-second timeout")
170+
171+
# Verify it exists
172+
assert cache.get(short_key) is not None, "Short-lived cache key should exist"
173+
logger.info("Verified short-lived cache key exists")
174+
175+
# Wait for expiration
176+
logger.info("Waiting for cache key to expire...")
177+
time.sleep(3)
178+
179+
# Verify it's gone
180+
assert cache.get(short_key) is None, "Cache key should have expired"
181+
logger.info("Verified cache key has expired as expected")
182+
183+
# Clean up
184+
cache.delete(cache_key)
185+
logger.info("Cleaned up test cache keys")
186+
187+
logger.info("All Django cache tests passed successfully!")
188+
return True
189+
190+
except Exception as e:
191+
logger.error(f"Cache operation error: {e}")
192+
return False
193+
194+
except ImportError as e:
195+
logger.error(f"Cache import error: {e}")
196+
return False
197+
except Exception as e:
198+
logger.error(f"Cache setup error: {e}")
199+
return False
200+
201+
def check_redis_installation():
202+
"""
203+
Check Redis client installation and version.
204+
"""
205+
try:
206+
logger.info(f"Redis client version: {redis.__version__}")
207+
208+
# Check if hiredis is installed
209+
try:
210+
import hiredis
211+
logger.info(f"Hiredis version: {hiredis.__version__}")
212+
except ImportError:
213+
logger.warning("Hiredis is not installed. For better performance, consider: pip install hiredis")
214+
215+
return True
216+
except Exception as e:
217+
logger.error(f"Error checking Redis installation: {e}")
218+
return False
219+
220+
if __name__ == '__main__':
221+
logger.info("Starting Redis tests...")
222+
223+
# Check Redis installation
224+
check_redis_installation()
225+
226+
# Test direct Redis connection
227+
redis_result = test_redis_connection()
228+
229+
# Test Django cache framework
230+
cache_result = test_django_cache()
231+
232+
if redis_result and cache_result:
233+
logger.info("\u2705 All Redis tests completed successfully!")
234+
else:
235+
logger.error("\u274c Some Redis tests failed!")
236+
logger.info("\nTo fix Redis connection issues:")
237+
logger.info("1. Make sure Redis is installed and running locally or Docker containers are running")
238+
logger.info("2. Check that the Redis URL in .env.local is correct")
239+
logger.info("3. For Docker setup, use 'localhost' when testing from host machine")
240+
logger.info("4. Install required Redis packages: pip install redis django-redis hiredis")

0 commit comments

Comments
 (0)