Spaces:
Running
Running
File size: 17,406 Bytes
8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 8de58aa 504a510 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | import pytest
import sys
import os
import tempfile
import json
import asyncio
from datetime import datetime, timedelta
import requests
import time
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from src.ai_system import SaemsTunesAISystem
from src.supabase_integration import AdvancedSupabaseIntegration
from src.security_system import AdvancedSecuritySystem
from src.monitoring_system import ComprehensiveMonitor
class TestAISystem:
"""Production AI system tests with real Supabase connections"""
def setup_method(self):
"""Setup real production test fixtures"""
# REAL SUPABASE CONNECTION - NO MOCKS
self.supabase_url = os.environ['SUPABASE_URL']
self.supabase_key = os.environ['SUPABASE_ANON_KEY']
self.supabase = AdvancedSupabaseIntegration(
supabase_url=self.supabase_url,
supabase_key=self.supabase_key
)
# REAL SECURITY SYSTEM - NO MOCKS
self.security = AdvancedSecuritySystem()
# REAL MONITORING SYSTEM - NO MOCKS
self.monitor = ComprehensiveMonitor(prometheus_port=8002)
# REAL AI SYSTEM WITH PRODUCTION MODEL - NO MOCKS
self.ai_system = SaemsTunesAISystem(
supabase_integration=self.supabase,
security_system=self.security,
monitor=self.monitor,
model_name="microsoft/Phi-3.5-mini-instruct",
model_repo="Thetima4/Phi-3.5-mini-instruct-Q4_K_M-GGUF",
model_file="Phi-3.5-mini-instruct-q4_k_m.gguf",
max_response_length=300,
temperature=0.7
)
# WAIT FOR SYSTEMS TO INITIALIZE
time.sleep(2)
def test_real_supabase_connection(self):
"""Test real Supabase connectivity with production database"""
assert self.supabase.is_connected() == True
# Test connection to actual Supabase tables
connection_test = self.supabase.test_connection()
assert connection_test['connected'] == True
# Verify we can access real tables
assert len(connection_test['tables']) > 0
assert connection_test['tables']['tracks']['accessible'] == True
assert connection_test['tables']['artists']['accessible'] == True
assert connection_test['tables']['courses']['accessible'] == True
def test_real_platform_stats_retrieval(self):
"""Test retrieving real platform statistics from production database"""
stats = self.supabase.get_platform_stats()
# Validate real data structure and values
assert isinstance(stats, dict)
assert 'track_count' in stats
assert 'artist_count' in stats
assert 'user_count' in stats
assert 'course_count' in stats
# These should be real counts from your production database
assert stats['track_count'] >= 0
assert stats['artist_count'] >= 0
assert stats['user_count'] >= 0
assert stats['course_count'] >= 0
# Test that we're getting actual database counts, not fallbacks
assert stats['track_count'] > 100 # Reasonable minimum for production
def test_real_music_context_retrieval(self):
"""Test retrieving real music context from production database"""
# Test with actual user query
query = "guitar lessons for beginners"
user_id = "test_user_123"
context = self.supabase.get_music_context(query, user_id)
# Validate real context structure
assert isinstance(context, dict)
assert 'tracks' in context
assert 'artists' in context
assert 'courses' in context
assert 'stats' in context
assert 'summary' in context
# Verify we're getting real data arrays
assert isinstance(context['tracks'], list)
assert isinstance(context['artists'], list)
assert isinstance(context['courses'], list)
# Test that context is tailored to the query
assert len(context['summary']) > 0
assert 'guitar' in context['summary'].lower() or 'lesson' in context['summary'].lower()
def test_real_popular_tracks_retrieval(self):
"""Test retrieving real popular tracks from production"""
tracks = self.supabase.get_popular_tracks(limit=5)
assert isinstance(tracks, list)
assert len(tracks) > 0
# Validate track structure with real data
for track in tracks:
assert 'id' in track
assert 'title' in track
assert 'artist' in track
assert 'genre' in track
assert 'plays' in track
assert isinstance(track['title'], str)
assert len(track['title']) > 0
assert isinstance(track['artist'], str)
assert len(track['artist']) > 0
def test_real_popular_artists_retrieval(self):
"""Test retrieving real artists from production"""
artists = self.supabase.get_popular_artists(limit=5)
assert isinstance(artists, list)
assert len(artists) > 0
# Validate artist structure with real data
for artist in artists:
assert 'id' in artist
assert 'name' in artist
assert 'genre' in artist
assert 'followers' in artist
assert isinstance(artist['name'], str)
assert len(artist['name']) > 0
def test_real_courses_retrieval(self):
"""Test retrieving real courses from production"""
courses = self.supabase.get_recent_courses(limit=5)
assert isinstance(courses, list)
assert len(courses) > 0
# Validate course structure with real data
for course in courses:
assert 'id' in course
assert 'title' in course
assert 'instructor' in course
assert 'level' in course
assert 'students' in course
assert isinstance(course['title'], str)
assert len(course['title']) > 0
def test_real_ai_system_health(self):
"""Test real AI system health and connectivity"""
system_info = self.ai_system.get_system_info()
assert isinstance(system_info, dict)
assert 'model_loaded' in system_info
assert 'model_name' in system_info
assert 'supabase_connected' in system_info
# Verify real system status
assert system_info['supabase_connected'] == True
assert system_info['model_name'] == "microsoft/Phi-3.5-mini-instruct"
def test_real_security_system_integration(self):
"""Test real security system with actual threat detection"""
query = "How do I create a playlist?"
user_id = "test_user_456"
ip_address = "192.168.1.100"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Test real security check
security_result = self.security.check_request(
query=query,
user_id=user_id,
ip_address=ip_address,
user_agent=user_agent
)
assert isinstance(security_result, dict)
assert 'is_suspicious' in security_result
assert 'risk_score' in security_result
assert 'allowed' in security_result
assert 'alerts' in security_result
# Should allow legitimate requests
assert security_result['allowed'] == True
assert security_result['is_suspicious'] == False
assert security_result['risk_score'] < 50
def test_real_monitoring_system_integration(self):
"""Test real monitoring system with actual metrics"""
# Record real inference metrics
test_metrics = {
'model_name': 'phi3.5-mini-Q4_K_M',
'processing_time_ms': 1250.5,
'input_tokens': 45,
'output_tokens': 120,
'total_tokens': 165,
'success': True,
'user_id': 'test_user_789',
'conversation_id': 'conv_123',
'timestamp': datetime.now(),
'query_length': 25,
'response_length': 180,
'model_hash': 'abc123def456'
}
self.monitor.record_inference(test_metrics)
# Test real performance summary
performance_summary = self.monitor.get_performance_summary(timedelta(minutes=5))
assert isinstance(performance_summary, dict)
if performance_summary: # Might be empty if no recent metrics
assert 'total_requests' in performance_summary
assert 'error_rate_percent' in performance_summary
assert 'avg_response_time_ms' in performance_summary
def test_real_system_health_monitoring(self):
"""Test real system health monitoring"""
health_status = self.monitor.get_system_health()
assert isinstance(health_status, dict)
assert 'status' in health_status
assert 'uptime_seconds' in health_status
assert 'performance' in health_status
assert 'alerts' in health_status
# Should be healthy in test environment
assert health_status['status'] in ['healthy', 'degraded', 'unhealthy']
assert health_status['uptime_seconds'] > 0
def test_real_ai_response_generation(self):
"""Test real AI response generation with production model"""
if not self.ai_system.model_loaded:
pytest.skip("Model not loaded, skipping response generation test")
query = "How can I learn guitar on Saem's Tunes?"
user_id = "music_learner_123"
# Generate real AI response with production model
response = self.ai_system.process_query(query, user_id)
# Validate real response
assert isinstance(response, str)
assert len(response) > 10
assert len(response) <= 500 # Should respect max response length
# Response should be relevant to the query
assert any(term in response.lower() for term in ['guitar', 'learn', 'course', 'lesson', 'music']) or len(response) > 0
def test_real_user_context_integration(self):
"""Test real user context retrieval from production database"""
# This would test with actual user data from your database
# Using a test user ID that exists in your production system
test_user_id = "existing_user_123" # Replace with actual test user ID
user_context = self.supabase.get_user_context(test_user_id)
assert isinstance(user_context, dict)
assert 'is_premium' in user_context
assert 'favorite_genres' in user_context
assert 'recent_activity' in user_context
assert 'learning_progress' in user_context
# These should be real user preferences from your database
assert isinstance(user_context['is_premium'], bool)
assert isinstance(user_context['favorite_genres'], list)
assert isinstance(user_context['recent_activity'], list)
assert isinstance(user_context['learning_progress'], dict)
def test_real_rate_limiting(self):
"""Test real rate limiting with actual security system"""
user_id = "rate_test_user"
ip_address = "192.168.1.200"
# Test multiple rapid requests to trigger rate limiting
for i in range(15):
security_result = self.security.check_request(
query=f"Test query {i}",
user_id=user_id,
ip_address=ip_address,
user_agent="Test Client"
)
if i > 10: # After 10 requests, might hit rate limits
# Either allowed or properly rate limited
assert security_result['allowed'] in [True, False]
else:
# Should be allowed for initial requests
assert security_result['allowed'] == True
# Reset rate limits for this user/IP
self.security.reset_rate_limits(user_id=user_id, ip_address=ip_address)
def test_real_supabase_detailed_stats(self):
"""Test retrieving detailed statistics from production database"""
detailed_stats = self.supabase.get_detailed_stats()
assert isinstance(detailed_stats, dict)
assert 'basic' in detailed_stats
assert 'content_breakdown' in detailed_stats
assert 'performance' in detailed_stats
# Validate basic stats structure
basic_stats = detailed_stats['basic']
assert 'track_count' in basic_stats
assert 'artist_count' in basic_stats
assert 'user_count' in basic_stats
# Validate content breakdown
content_breakdown = detailed_stats['content_breakdown']
assert 'tracks_by_popularity' in content_breakdown
assert 'artists_by_followers' in content_breakdown
assert 'courses_by_rating' in content_breakdown
# These should be real data distributions from your database
assert isinstance(content_breakdown['tracks_by_popularity'], list)
assert isinstance(content_breakdown['artists_by_followers'], list)
assert isinstance(content_breakdown['courses_by_rating'], list)
def test_real_conversation_history(self):
"""Test real conversation history functionality"""
conversation_id = "test_conv_123"
user_id = "conv_test_user"
if not self.ai_system.model_loaded:
pytest.skip("Model not loaded, skipping conversation test")
# First query
query1 = "What music courses do you offer?"
response1 = self.ai_system.process_query(query1, user_id, conversation_id)
# Second query with conversation context
query2 = "Which ones are good for beginners?"
response2 = self.ai_system.process_query(query2, user_id, conversation_id)
# Both should generate valid responses
assert isinstance(response1, str)
assert len(response1) > 0
assert isinstance(response2, str)
assert len(response2) > 0
# Conversation history should be maintained
assert conversation_id in self.ai_system.conversation_history
conversation = self.ai_system.conversation_history[conversation_id]
assert len(conversation) >= 4 # At least 2 user + 2 assistant messages
def test_real_error_handling(self):
"""Test real error handling with production systems"""
# Test with malformed query that might cause issues
problematic_query = "A" * 10000 # Very long query
security_result = self.security.check_request(
query=problematic_query,
user_id="error_test_user",
ip_address="192.168.1.300"
)
# Security system should flag extremely long queries
assert security_result['risk_score'] > 0
assert any('long' in alert.lower() for alert in security_result['alerts'])
def test_real_cache_functionality(self):
"""Test real response caching in AI system"""
if not self.ai_system.model_loaded:
pytest.skip("Model not loaded, skipping cache test")
query = "How do I upload my music to Saem's Tunes?"
user_id = "cache_test_user"
# First request - should process normally
start_time = time.time()
response1 = self.ai_system.process_query(query, user_id)
first_duration = time.time() - start_time
# Second request - should be faster if cached
start_time = time.time()
response2 = self.ai_system.process_query(query, user_id)
second_duration = time.time() - start_time
# Responses should be identical
assert response1 == response2
# Second request should be faster (cached)
# Note: This might not always hold true in production, but generally should
assert second_duration <= first_duration * 0.5 # Should be at least 50% faster
def test_real_system_cleanup(self):
"""Test real system cleanup and resource management"""
# Test cache clearing
initial_cache_size = len(self.ai_system.response_cache)
self.ai_system.clear_cache()
final_cache_size = len(self.ai_system.response_cache)
assert final_cache_size == 0
assert final_cache_size < initial_cache_size or initial_cache_size == 0
# Test security system cleanup
initial_security_log_size = len(self.security.security_log)
self.security.security_log = [] # Clear security log
assert len(self.security.security_log) == 0
# Test monitoring system reset
self.monitor.reset_metrics()
recent_metrics = self.monitor.get_recent_metrics(minutes=1)
assert len(recent_metrics) == 0
def teardown_method(self):
"""Cleanup after tests"""
if hasattr(self, 'monitor'):
self.monitor.stop_monitoring()
if hasattr(self, 'ai_system'):
self.ai_system.clear_cache() |