Coverage for src / moai_adk / core / integration / utils.py: 35.71%

70 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-20 20:52 +0900

1""" 

2Integration testing utilities and helper functions. 

3 

4This module contains utility functions for component discovery, 

5dependency resolution, and test result analysis. 

6""" 

7 

8import shutil 

9import tempfile 

10from pathlib import Path 

11from typing import Any, Dict, List, Optional 

12 

13from .models import IntegrationTestResult, TestComponent 

14 

15 

16class ComponentDiscovery: 

17 """ 

18 Component discovery utilities for integration testing. 

19 """ 

20 

21 @staticmethod 

22 def discover_components(base_path: str) -> List[TestComponent]: 

23 """ 

24 Discover testable components in the given path. 

25 

26 Args: 

27 base_path: Base path to search for components 

28 

29 Returns: 

30 List of discovered components 

31 """ 

32 components = [] 

33 base_dir = Path(base_path) 

34 

35 if not base_dir.exists(): 

36 return components 

37 

38 # Look for Python modules 

39 for py_file in base_dir.rglob("*.py"): 

40 if py_file.name.startswith("__"): 

41 continue 

42 

43 relative_path = py_file.relative_to(base_dir) 

44 module_name = str(relative_path.with_suffix("")).replace("/", ".") 

45 

46 component = TestComponent( 

47 name=module_name, 

48 component_type="python_module", 

49 version="1.0.0", # Default version 

50 ) 

51 components.append(component) 

52 

53 return components 

54 

55 @staticmethod 

56 def resolve_dependencies(components: List[TestComponent]) -> Dict[str, List[str]]: 

57 """ 

58 Resolve dependencies between components. 

59 

60 Args: 

61 components: List of components to analyze 

62 

63 Returns: 

64 Dictionary mapping component names to their dependencies 

65 """ 

66 dependency_map = {} 

67 

68 for component in components: 

69 try: 

70 # Try to import and analyze dependencies 

71 dependencies = ComponentDiscovery._analyze_imports(component) 

72 dependency_map[component.name] = dependencies 

73 except Exception: 

74 dependency_map[component.name] = component.dependencies 

75 

76 return dependency_map 

77 

78 @staticmethod 

79 def _analyze_imports(component: TestComponent) -> List[str]: 

80 """ 

81 Analyze imports for a component to determine dependencies. 

82 

83 Args: 

84 component: Component to analyze 

85 

86 Returns: 

87 List of dependency names 

88 """ 

89 # This is a simplified implementation 

90 # In a real scenario, you would parse the source code 

91 return component.dependencies 

92 

93 

94class TestResultAnalyzer: 

95 """ 

96 Test result analysis utilities. 

97 """ 

98 

99 @staticmethod 

100 def calculate_success_rate(results: List[IntegrationTestResult]) -> float: 

101 """ 

102 Calculate the success rate of test results. 

103 

104 Args: 

105 results: List of test results 

106 

107 Returns: 

108 Success rate as percentage (0-100) 

109 """ 

110 if not results: 

111 return 0.0 

112 

113 passed = sum(1 for result in results if result.passed) 

114 return (passed / len(results)) * 100 

115 

116 @staticmethod 

117 def get_failed_tests( 

118 results: List[IntegrationTestResult], 

119 ) -> List[IntegrationTestResult]: 

120 """ 

121 Get list of failed tests. 

122 

123 Args: 

124 results: List of test results 

125 

126 Returns: 

127 List of failed test results 

128 """ 

129 return [result for result in results if not result.passed] 

130 

131 @staticmethod 

132 def get_execution_stats(results: List[IntegrationTestResult]) -> Dict[str, Any]: 

133 """ 

134 Get execution statistics for test results. 

135 

136 Args: 

137 results: List of test results 

138 

139 Returns: 

140 Dictionary with execution statistics 

141 """ 

142 if not results: 

143 return { 

144 "total": 0, 

145 "passed": 0, 

146 "failed": 0, 

147 "success_rate": 0.0, 

148 "total_time": 0.0, 

149 "avg_time": 0.0, 

150 } 

151 

152 passed = sum(1 for result in results if result.passed) 

153 failed = len(results) - passed 

154 total_time = sum(result.execution_time for result in results) 

155 

156 return { 

157 "total": len(results), 

158 "passed": passed, 

159 "failed": failed, 

160 "success_rate": TestResultAnalyzer.calculate_success_rate(results), 

161 "total_time": total_time, 

162 "avg_time": total_time / len(results), 

163 } 

164 

165 

166class TestEnvironment: 

167 """ 

168 Test environment management utilities. 

169 """ 

170 

171 def __init__(self, temp_dir: Optional[str] = None): 

172 """ 

173 Initialize test environment. 

174 

175 Args: 

176 temp_dir: Optional temporary directory path 

177 """ 

178 self.temp_dir = temp_dir 

179 self.created_temp = False 

180 

181 if self.temp_dir is None: 

182 self.temp_dir = tempfile.mkdtemp(prefix="moai_integration_test_") 

183 self.created_temp = True 

184 

185 def cleanup(self): 

186 """Clean up test environment.""" 

187 if self.created_temp and self.temp_dir: 

188 try: 

189 shutil.rmtree(self.temp_dir) 

190 except Exception: 

191 pass # Ignore cleanup errors 

192 

193 def get_temp_path(self, name: str) -> str: 

194 """ 

195 Get a temporary file path. 

196 

197 Args: 

198 name: File name 

199 

200 Returns: 

201 Full path to temporary file 

202 """ 

203 return str(Path(self.temp_dir) / name) 

204 

205 def __enter__(self): 

206 """Context manager entry.""" 

207 return self 

208 

209 def __exit__(self, exc_type, exc_val, exc_tb): 

210 """Context manager exit.""" 

211 self.cleanup()