CoolFace
Apppublic

findEthics/Atlas

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
test_performance_user_auth.py604 linesDownload Raw Back to tests
1#!/usr/bin/env python32"""3Performance tests for user authentication feature4 5This test file focuses on performance testing of user_id queries, indexes,6and analytics functions to ensure the user authentication feature doesn't7negatively impact system performance.8"""9 10import sys11import os12sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))13 14# Load environment variables15try:16    from dotenv import load_dotenv17    load_dotenv()18except ImportError:19    pass  # dotenv not available, continue without it20 21import asyncio22import time23import random24import string25from datetime import datetime, timedelta26from typing import List, Dict, Any27 28from analytics.collectors import create_session, track_message, track_search29from analytics.dashboard import (30    get_user_statistics,31    get_user_analytics,32    get_authenticated_vs_anonymous_metrics,33    get_basic_stats,34    get_hourly_message_stats35)36from analytics.database import (37    get_sessions_collection,38    get_messages_collection,39    get_search_analytics_collection40)41 42 43class TestDatabaseIndexPerformance:44    """Test performance of database indexes for user_id queries"""45    46    async def test_user_id_index_performance(self):47        """Test performance of user_id index queries"""48        print("๐Ÿ” Testing user_id index performance...")49        50        # Create test data with multiple users51        user_ids = [f"perf_user_{i}" for i in range(20)]52        sessions_per_user = 353        messages_per_session = 554        55        print(f"Creating test data: {len(user_ids)} users, {sessions_per_user} sessions each, {messages_per_session} messages each")56        57        # Create test data58        start_time = time.time()59        all_sessions = []60        61        for user_id in user_ids:62            for session_num in range(sessions_per_user):63                session = await create_session(user_id=user_id)64                all_sessions.append((session, user_id))65                66                for msg_num in range(messages_per_session):67                    await track_message(68                        session_id=session.session_id,69                        prompt_length=random.randint(20, 100),70                        response_length=random.randint(50, 200),71                        response_time_ms=random.randint(500, 2000),72                        used_search=random.choice([True, False]),73                        user_id=user_id74                    )75        76        data_creation_time = time.time() - start_time77        print(f"โœ… Test data created in {data_creation_time:.2f} seconds")78        79        # Test query performance80        sessions_collection = await get_sessions_collection()81        messages_collection = await get_messages_collection()82        83        if sessions_collection and messages_collection:84            # Test individual user queries85            print("Testing individual user queries...")86            start_time = time.time()87            88            for user_id in user_ids:89                user_sessions = await sessions_collection.count_documents({"user_id": user_id})90                assert user_sessions == sessions_per_user91                92                user_messages = await messages_collection.count_documents({"user_id": user_id})93                assert user_messages == sessions_per_user * messages_per_session94            95            individual_query_time = time.time() - start_time96            avg_query_time = individual_query_time / len(user_ids)97            98            print(f"โœ… Individual user queries: {individual_query_time:.2f}s total, {avg_query_time:.4f}s average")99            100            # Performance assertion101            assert avg_query_time < 0.1, f"Individual queries too slow: {avg_query_time:.4f}s average"102            103            # Test bulk queries104            print("Testing bulk user queries...")105            start_time = time.time()106            107            # Query all authenticated sessions108            auth_sessions = await sessions_collection.count_documents({"user_id": {"$ne": None}})109            assert auth_sessions == len(user_ids) * sessions_per_user110            111            # Query all authenticated messages112            auth_messages = await messages_collection.count_documents({"user_id": {"$ne": None}})113            assert auth_messages == len(user_ids) * sessions_per_user * messages_per_session114            115            bulk_query_time = time.time() - start_time116            print(f"โœ… Bulk queries: {bulk_query_time:.2f}s")117            118            # Performance assertion119            assert bulk_query_time < 2.0, f"Bulk queries too slow: {bulk_query_time:.2f}s"120            121        else:122            print("โš ๏ธ  Database not available - skipping index performance test")123    124    async def test_compound_index_performance(self):125        """Test performance of compound (user_id, timestamp) index queries"""126        print("๐Ÿ” Testing compound index performance...")127        128        # Create test data with timestamps spread over time129        user_id = "compound_perf_user"130        session = await create_session(user_id=user_id)131        132        num_messages = 100133        print(f"Creating {num_messages} messages with varied timestamps...")134        135        start_time = time.time()136        base_time = datetime.utcnow()137        138        for i in range(num_messages):139            # Create messages with timestamps spread over the last 24 hours140            timestamp_offset = timedelta(hours=random.uniform(0, 24))141            message_time = base_time - timestamp_offset142            143            await track_message(144                session_id=session.session_id,145                prompt_length=50,146                response_length=100,147                response_time_ms=1000,148                user_id=user_id149            )150            151            # Small delay to ensure different timestamps152            await asyncio.sleep(0.001)153        154        data_creation_time = time.time() - start_time155        print(f"โœ… Test data created in {data_creation_time:.2f} seconds")156        157        # Test compound queries158        messages_collection = await get_messages_collection()159        160        if messages_collection:161            # Test various time range queries162            time_ranges = [163                ("1 hour", timedelta(hours=1)),164                ("6 hours", timedelta(hours=6)),165                ("12 hours", timedelta(hours=12)),166                ("24 hours", timedelta(hours=24))167            ]168            169            for range_name, time_delta in time_ranges:170                start_time = time.time()171                cutoff_time = datetime.utcnow() - time_delta172                173                recent_messages = await messages_collection.count_documents({174                    "user_id": user_id,175                    "timestamp": {"$gte": cutoff_time}176                })177                178                query_time = time.time() - start_time179                print(f"โœ… {range_name} query: {query_time:.4f}s ({recent_messages} messages)")180                181                # Performance assertion182                assert query_time < 0.5, f"{range_name} query too slow: {query_time:.4f}s"183        184        else:185            print("โš ๏ธ  Database not available - skipping compound index test")186    187    async def test_sparse_index_performance(self):188        """Test performance of sparse indexes with mixed null/non-null user_id values"""189        print("๐Ÿ” Testing sparse index performance...")190        191        # Create mixed data (authenticated and anonymous)192        num_auth_users = 10193        num_anon_sessions = 20194        messages_per_session = 5195        196        print(f"Creating mixed data: {num_auth_users} auth users, {num_anon_sessions} anon sessions")197        198        start_time = time.time()199        200        # Create authenticated user data201        auth_sessions = []202        for i in range(num_auth_users):203            user_id = f"sparse_user_{i}"204            session = await create_session(user_id=user_id)205            auth_sessions.append(session)206            207            for j in range(messages_per_session):208                await track_message(209                    session_id=session.session_id,210                    prompt_length=50,211                    response_length=100,212                    response_time_ms=1000,213                    user_id=user_id214                )215        216        # Create anonymous user data217        anon_sessions = []218        for i in range(num_anon_sessions):219            session = await create_session(user_id=None)220            anon_sessions.append(session)221            222            for j in range(messages_per_session):223                await track_message(224                    session_id=session.session_id,225                    prompt_length=50,226                    response_length=100,227                    response_time_ms=1000,228                    user_id=None229                )230        231        data_creation_time = time.time() - start_time232        print(f"โœ… Mixed data created in {data_creation_time:.2f} seconds")233        234        # Test sparse index queries235        sessions_collection = await get_sessions_collection()236        messages_collection = await get_messages_collection()237        238        if sessions_collection and messages_collection:239            # Test authenticated user queries240            start_time = time.time()241            auth_session_count = await sessions_collection.count_documents({"user_id": {"$ne": None}})242            auth_query_time = time.time() - start_time243            244            assert auth_session_count >= num_auth_users245            print(f"โœ… Authenticated sessions query: {auth_query_time:.4f}s ({auth_session_count} sessions)")246            247            # Test anonymous user queries248            start_time = time.time()249            anon_session_count = await sessions_collection.count_documents({"user_id": None})250            anon_query_time = time.time() - start_time251            252            assert anon_session_count >= num_anon_sessions253            print(f"โœ… Anonymous sessions query: {anon_query_time:.4f}s ({anon_session_count} sessions)")254            255            # Test specific user queries256            start_time = time.time()257            specific_user_sessions = await sessions_collection.count_documents({"user_id": "sparse_user_0"})258            specific_query_time = time.time() - start_time259            260            assert specific_user_sessions == 1261            print(f"โœ… Specific user query: {specific_query_time:.4f}s")262            263            # Performance assertions264            assert auth_query_time < 0.5, f"Auth query too slow: {auth_query_time:.4f}s"265            assert anon_query_time < 0.5, f"Anon query too slow: {anon_query_time:.4f}s"266            assert specific_query_time < 0.1, f"Specific query too slow: {specific_query_time:.4f}s"267        268        else:269            print("โš ๏ธ  Database not available - skipping sparse index test")270 271 272class TestAnalyticsFunctionPerformance:273    """Test performance of analytics functions with user authentication"""274    275    async def test_user_statistics_performance(self):276        """Test performance of get_user_statistics function"""277        print("๐Ÿ“Š Testing user statistics performance...")278        279        # Create test data280        await self._create_performance_test_data()281        282        # Test get_user_statistics performance283        start_time = time.time()284        user_stats = await get_user_statistics()285        stats_time = time.time() - start_time286        287        assert isinstance(user_stats, dict)288        assert "unique_authenticated_users" in user_stats289        assert "authenticated_sessions" in user_stats290        assert "anonymous_sessions" in user_stats291        292        print(f"โœ… User statistics query: {stats_time:.4f}s")293        294        # Performance assertion295        assert stats_time < 5.0, f"User statistics too slow: {stats_time:.4f}s"296    297    async def test_user_analytics_performance(self):298        """Test performance of get_user_analytics function"""299        print("๐Ÿ“Š Testing individual user analytics performance...")300        301        # Create test user with substantial data302        user_id = "analytics_perf_user"303        session = await create_session(user_id=user_id)304        305        # Create many messages for this user306        num_messages = 50307        print(f"Creating {num_messages} messages for performance test...")308        309        for i in range(num_messages):310            await track_message(311                session_id=session.session_id,312                prompt_length=random.randint(20, 100),313                response_length=random.randint(50, 200),314                response_time_ms=random.randint(500, 2000),315                used_search=random.choice([True, False]),316                user_id=user_id317            )318        319        # Test get_user_analytics performance320        start_time = time.time()321        user_analytics = await get_user_analytics(user_id)322        analytics_time = time.time() - start_time323        324        assert isinstance(user_analytics, dict)325        assert user_analytics.get("user_id") == user_id326        assert user_analytics.get("total_messages") == num_messages327        328        print(f"โœ… User analytics query: {analytics_time:.4f}s")329        330        # Performance assertion331        assert analytics_time < 3.0, f"User analytics too slow: {analytics_time:.4f}s"332    333    async def test_authenticated_vs_anonymous_performance(self):334        """Test performance of get_authenticated_vs_anonymous_metrics function"""335        print("๐Ÿ“Š Testing authenticated vs anonymous metrics performance...")336        337        # Create mixed test data338        await self._create_performance_test_data()339        340        # Test get_authenticated_vs_anonymous_metrics performance341        start_time = time.time()342        comparison_metrics = await get_authenticated_vs_anonymous_metrics()343        comparison_time = time.time() - start_time344        345        assert isinstance(comparison_metrics, dict)346        assert "authenticated" in comparison_metrics347        assert "anonymous" in comparison_metrics348        assert "comparison" in comparison_metrics349        350        print(f"โœ… Comparison metrics query: {comparison_time:.4f}s")351        352        # Performance assertion353        assert comparison_time < 5.0, f"Comparison metrics too slow: {comparison_time:.4f}s"354    355    async def test_basic_stats_with_filter_performance(self):356        """Test performance of get_basic_stats with user_id filter"""357        print("๐Ÿ“Š Testing filtered basic stats performance...")358        359        # Create test data360        await self._create_performance_test_data()361        362        # Test unfiltered stats363        start_time = time.time()364        all_stats = await get_basic_stats()365        all_stats_time = time.time() - start_time366        367        print(f"โœ… Unfiltered basic stats: {all_stats_time:.4f}s")368        369        # Test filtered stats370        start_time = time.time()371        filtered_stats = await get_basic_stats(user_id="perf_test_user_0")372        filtered_stats_time = time.time() - start_time373        374        assert "filtered_by_user_id" in filtered_stats375        print(f"โœ… Filtered basic stats: {filtered_stats_time:.4f}s")376        377        # Performance assertions378        assert all_stats_time < 3.0, f"Unfiltered stats too slow: {all_stats_time:.4f}s"379        assert filtered_stats_time < 2.0, f"Filtered stats too slow: {filtered_stats_time:.4f}s"380    381    async def test_hourly_stats_with_filter_performance(self):382        """Test performance of get_hourly_message_stats with user_id filter"""383        print("๐Ÿ“Š Testing filtered hourly stats performance...")384        385        # Create test data386        await self._create_performance_test_data()387        388        # Test unfiltered hourly stats389        start_time = time.time()390        all_hourly = await get_hourly_message_stats(hours=24)391        all_hourly_time = time.time() - start_time392        393        print(f"โœ… Unfiltered hourly stats: {all_hourly_time:.4f}s")394        395        # Test filtered hourly stats396        start_time = time.time()397        filtered_hourly = await get_hourly_message_stats(hours=24, user_id="perf_test_user_0")398        filtered_hourly_time = time.time() - start_time399        400        print(f"โœ… Filtered hourly stats: {filtered_hourly_time:.4f}s")401        402        # Performance assertions403        assert all_hourly_time < 3.0, f"Unfiltered hourly stats too slow: {all_hourly_time:.4f}s"404        assert filtered_hourly_time < 2.0, f"Filtered hourly stats too slow: {filtered_hourly_time:.4f}s"405    406    async def _create_performance_test_data(self):407        """Create test data for performance testing"""408        # Create authenticated users409        for i in range(5):410            user_id = f"perf_test_user_{i}"411            session = await create_session(user_id=user_id)412            413            # Create messages for each user414            for j in range(10):415                await track_message(416                    session_id=session.session_id,417                    prompt_length=random.randint(20, 100),418                    response_length=random.randint(50, 200),419                    response_time_ms=random.randint(500, 2000),420                    used_search=random.choice([True, False]),421                    user_id=user_id422                )423        424        # Create anonymous users425        for i in range(3):426            session = await create_session(user_id=None)427            428            # Create messages for anonymous users429            for j in range(8):430                await track_message(431                    session_id=session.session_id,432                    prompt_length=random.randint(20, 100),433                    response_length=random.randint(50, 200),434                    response_time_ms=random.randint(500, 2000),435                    used_search=random.choice([True, False]),436                    user_id=None437                )438 439 440class TestConcurrentUserPerformance:441    """Test performance with concurrent user operations"""442    443    async def test_concurrent_user_creation(self):444        """Test performance of concurrent user session creation"""445        print("๐Ÿš€ Testing concurrent user creation performance...")446        447        num_concurrent_users = 20448        449        async def create_user_session(user_id: str):450            session = await create_session(user_id=user_id)451            452            # Create a few messages for each user453            for i in range(3):454                await track_message(455                    session_id=session.session_id,456                    prompt_length=50,457                    response_length=100,458                    response_time_ms=1000,459                    user_id=user_id460                )461            462            return session463        464        # Create concurrent tasks465        start_time = time.time()466        tasks = [467            create_user_session(f"concurrent_user_{i}")468            for i in range(num_concurrent_users)469        ]470        471        sessions = await asyncio.gather(*tasks)472        concurrent_time = time.time() - start_time473        474        assert len(sessions) == num_concurrent_users475        print(f"โœ… Concurrent user creation: {concurrent_time:.2f}s for {num_concurrent_users} users")476        477        # Performance assertion478        avg_time_per_user = concurrent_time / num_concurrent_users479        assert avg_time_per_user < 1.0, f"Concurrent creation too slow: {avg_time_per_user:.2f}s per user"480    481    async def test_concurrent_user_queries(self):482        """Test performance of concurrent user-specific queries"""483        print("๐Ÿš€ Testing concurrent user query performance...")484        485        # Create test users first486        user_ids = [f"query_user_{i}" for i in range(10)]487        488        for user_id in user_ids:489            session = await create_session(user_id=user_id)490            await track_message(491                session_id=session.session_id,492                prompt_length=50,493                response_length=100,494                response_time_ms=1000,495                user_id=user_id496            )497        498        # Test concurrent queries499        async def query_user_analytics(user_id: str):500            return await get_user_analytics(user_id)501        502        start_time = time.time()503        tasks = [query_user_analytics(user_id) for user_id in user_ids]504        results = await asyncio.gather(*tasks)505        concurrent_query_time = time.time() - start_time506        507        assert len(results) == len(user_ids)508        for i, result in enumerate(results):509            assert result.get("user_id") == user_ids[i]510        511        print(f"โœ… Concurrent user queries: {concurrent_query_time:.2f}s for {len(user_ids)} users")512        513        # Performance assertion514        avg_query_time = concurrent_query_time / len(user_ids)515        assert avg_query_time < 0.5, f"Concurrent queries too slow: {avg_query_time:.2f}s per query"516 517 518class TestMemoryPerformance:519    """Test memory usage with user authentication"""520    521    async def test_memory_usage_with_users(self):522        """Test that user_id fields don't significantly increase memory usage"""523        print("๐Ÿ’พ Testing memory usage with user authentication...")524        525        import psutil526        import os527        528        # Get initial memory usage529        process = psutil.Process(os.getpid())530        initial_memory = process.memory_info().rss / 1024 / 1024  # MB531        532        # Create substantial amount of data533        num_users = 50534        messages_per_user = 20535        536        print(f"Creating {num_users} users with {messages_per_user} messages each...")537        538        for i in range(num_users):539            user_id = f"memory_test_user_{i}"540            session = await create_session(user_id=user_id)541            542            for j in range(messages_per_user):543                await track_message(544                    session_id=session.session_id,545                    prompt_length=50,546                    response_length=100,547                    response_time_ms=1000,548                    user_id=user_id549                )550        551        # Get final memory usage552        final_memory = process.memory_info().rss / 1024 / 1024  # MB553        memory_increase = final_memory - initial_memory554        555        print(f"โœ… Memory usage: {initial_memory:.1f}MB โ†’ {final_memory:.1f}MB (+{memory_increase:.1f}MB)")556        557        # Memory increase should be reasonable558        total_records = num_users * (1 + messages_per_user)  # sessions + messages559        memory_per_record = memory_increase / total_records560        561        print(f"โœ… Memory per record: {memory_per_record:.3f}MB")562        563        # Performance assertion (should be less than 1MB per record)564        assert memory_per_record < 1.0, f"Memory usage too high: {memory_per_record:.3f}MB per record"565 566 567async def run_performance_tests():568    """Run all performance tests"""569    print("โšก Running Performance Tests for User Authentication")570    print("=" * 60)571    572    # Test database index performance573    index_test = TestDatabaseIndexPerformance()574    await index_test.test_user_id_index_performance()575    await index_test.test_compound_index_performance()576    await index_test.test_sparse_index_performance()577    print("โœ… Database index performance tests completed")578    579    # Test analytics function performance580    analytics_test = TestAnalyticsFunctionPerformance()581    await analytics_test.test_user_statistics_performance()582    await analytics_test.test_user_analytics_performance()583    await analytics_test.test_authenticated_vs_anonymous_performance()584    await analytics_test.test_basic_stats_with_filter_performance()585    await analytics_test.test_hourly_stats_with_filter_performance()586    print("โœ… Analytics function performance tests completed")587    588    # Test concurrent performance589    concurrent_test = TestConcurrentUserPerformance()590    await concurrent_test.test_concurrent_user_creation()591    await concurrent_test.test_concurrent_user_queries()592    print("โœ… Concurrent performance tests completed")593    594    # Test memory performance595    memory_test = TestMemoryPerformance()596    await memory_test.test_memory_usage_with_users()597    print("โœ… Memory performance tests completed")598    599    print("\n๐ŸŽ‰ ALL PERFORMANCE TESTS COMPLETED!")600    print("User authentication feature maintains good performance characteristics.")601 602 603if __name__ == "__main__":604    asyncio.run(run_performance_tests())