""" TraceStudio 执行引擎和缓存系统集成测试 """ import sys import asyncio from pathlib import Path import time # 添加项目根目录到路径 project_root = Path(__file__).parent.parent.parent sys.path.insert(0, str(project_root)) from server.app.core.cache_manager import CacheManager, MemoryCache, DiskCache, CacheEvictionPolicy from server.app.core.workflow_executor import WorkflowExecutor, WorkflowGraph from server.app.nodes.example_nodes import AddNode, MultiplyNode # ============= 测试 1: 内存缓存 ============= def test_memory_cache(): """测试内存缓存""" print("\n" + "="*60) print("测试 1: 内存缓存") print("="*60) cache = MemoryCache(max_size=3, ttl=None, policy=CacheEvictionPolicy.LRU) # 添加数据 cache.set("key1", {"value": 1}) cache.set("key2", {"value": 2}) cache.set("key3", {"value": 3}) print("✅ 添加 3 个缓存项") # 获取数据 assert cache.get("key1") == {"value": 1} print("✅ 成功获取 key1") # 触发淘汰(LRU) cache.set("key4", {"value": 4}) print("✅ 添加第 4 个项,触发 LRU 淘汰") # key2 应该被淘汰(最久未使用) assert cache.get("key2") is None print("✅ key2 被淘汰(LRU)") # 统计 stats = cache.get_stats() print(f"\n缓存统计: {stats}") def test_disk_cache(): """测试磁盘缓存""" print("\n" + "="*60) print("测试 2: 磁盘缓存") print("="*60) cache_dir = Path("/tmp/tracestudio_cache_test") cache = DiskCache(cache_dir, ttl=None) # 设置数据 cache.set("test_key", {"data": "test_value", "count": 42}) print("✅ 设置磁盘缓存") # 获取数据 result = cache.get("test_key") assert result == {"data": "test_value", "count": 42} print("✅ 成功获取磁盘缓存数据") # 统计 stats = cache.get_stats() print(f"\n缓存统计: {stats}") # 清理 cache.clear() print("✅ 清理磁盘缓存") def test_cache_ttl(): """测试缓存 TTL""" print("\n" + "="*60) print("测试 3: 缓存 TTL") print("="*60) cache = MemoryCache(max_size=100, ttl=1) # 1 秒过期 # 设置数据 cache.set("expire_key", {"value": "will_expire"}) print("✅ 设置缓存(1秒过期)") # 立即获取 assert cache.get("expire_key") == {"value": "will_expire"} print("✅ 立即获取成功") # 等待过期 print("⏳ 等待 1.1 秒...") time.sleep(1.1) # 再次获取应该返回 None assert cache.get("expire_key") is None print("✅ 过期后返回 None") # ============= 测试 4: 工作流图 ============= def test_workflow_graph(): """测试工作流图""" print("\n" + "="*60) print("测试 4: 工作流图") print("="*60) graph = WorkflowGraph() # 添加节点 # 按照执行器约定:type 使用 NodeType 值(例如 'normal'),实现类名放到 class_name graph.add_node("n1", "normal", {"offset": 0}) graph.nodes["n1"]["class_name"] = "AddNode" graph.add_node("n2", "normal", {"scale": 2.0}) graph.nodes["n2"]["class_name"] = "MultiplyNode" graph.add_node("n3", "normal", {"offset": 10}) graph.nodes["n3"]["class_name"] = "AddNode" print("✅ 添加 3 个节点") # 添加连接 graph.add_edge("n1", "result", "n2", "a") graph.add_edge("n2", "result", "n3", "a") print("✅ 添加连接: n1 -> n2 -> n3") # 获取依赖 deps = graph.get_dependencies("n3") assert "n1" in deps and "n2" in deps print(f"✅ n3 的依赖: {deps}") # 拓扑排序 order = graph.topological_sort() assert order == ["n1", "n2", "n3"] print(f"✅ 拓扑排序: {order}") # 检查循环 assert not graph.has_cycle() print("✅ 无循环依赖") # ============= 测试 5: 工作流执行 ============= async def test_workflow_execution(): """测试工作流执行""" print("\n" + "="*60) print("测试 5: 工作流执行") print("="*60) executor = WorkflowExecutor(user_id="test_user") # 定义工作流 nodes = [ { "id": "add_node", "type": "AddNode", "params": {"offset": 5} }, { "id": "multiply_node", "type": "MultiplyNode", "params": {"scale": 2.0} } ] # 边定义:add_node.result -> multiply_node.a edges = [ { "source": "add_node", "source_port": "result", "target": "multiply_node", "target_port": "a" } ] # add_node 的 a、b,multiply_node 的 b 都由全局 context 提供 global_context = {"a": 3, "b": 4} try: success, report = await executor.execute(nodes, edges, global_context=global_context) if success: print(f"✅ 工作流执行成功") print(f" 执行 ID: {report.get('execution_id')}") print(f" 总耗时: {report.get('total_duration', 0):.3f}s") print(f" 节点数: {len(report.get('nodes', {}))}") for node_id, info in report.get('nodes', {}).items(): print(f" - {node_id}: {info.get('status')}") else: print(f"❌ 工作流执行失败: {report.get('error') if report else 'Unknown error'}") if report: print(f" 详情: {report}") except Exception as e: print(f"❌ 执行异常: {e}") import traceback traceback.print_exc() # ============= 测试 6: 缓存集成 ============= def test_cache_manager(): """测试缓存管理器""" print("\n" + "="*60) print("测试 6: 缓存管理器") print("="*60) # 初始化缓存 CacheManager.init_memory_cache(max_size=100, ttl=None) CacheManager.init_disk_cache(Path("/tmp/tracestudio_cache"), ttl=None) print("✅ 初始化内存和磁盘缓存") # 设置数据 CacheManager.set("test_key", {"data": "value"}, storage="memory") CacheManager.set("test_key2", {"data": "value2"}, storage="disk") print("✅ 分别设置内存和磁盘缓存") # 获取数据 assert CacheManager.get("test_key", prefer="memory") == {"data": "value"} assert CacheManager.get("test_key2", prefer="disk") == {"data": "value2"} print("✅ 成功获取数据") # 同时设置 CacheManager.set_both("both_key", {"data": "both"}) assert CacheManager.get("both_key") == {"data": "both"} print("✅ 同时设置内存和磁盘缓存成功") # 统计 stats = CacheManager.get_stats() print(f"\n缓存统计:") if stats.get("memory"): print(f" 内存: {stats['memory']}") if stats.get("disk"): print(f" 磁盘: {stats['disk']}") # 清理 CacheManager.clear() print("✅ 清理所有缓存") if __name__ == "__main__": print("\n" + "🧪 TraceStudio 执行引擎和缓存系统测试".center(60, "=")) try: # 运行测试 test_memory_cache() test_disk_cache() test_cache_ttl() test_workflow_graph() asyncio.run(test_workflow_execution()) test_cache_manager() print("\n" + "="*60) print("✅ 所有测试通过!") print("="*60 + "\n") except Exception as e: print("\n" + "="*60) print(f"❌ 测试失败: {e}") print("="*60 + "\n") import traceback traceback.print_exc()