MCPcopy Create free account
hub / github.com/AutoForgeAI/autoforge / _get_test_batch

Method _get_test_batch

parallel_orchestrator.py:259–361  ·  view source on GitHub ↗

Select a prioritized batch of passing features for regression testing. Uses weighted scoring to prioritize features that: 1. Haven't been tested recently in this orchestrator session 2. Are depended on by many other features (higher impact if broken) 3. Have more dep

(self, batch_size: int = 3)

Source from the content-addressed store, hash-verified

257 session.close()
258
259 def _get_test_batch(self, batch_size: int = 3) -> list[int]:
260 """Select a prioritized batch of passing features for regression testing.
261
262 Uses weighted scoring to prioritize features that:
263 1. Haven't been tested recently in this orchestrator session
264 2. Are depended on by many other features (higher impact if broken)
265 3. Have more dependencies themselves (complex integration points)
266
267 When all passing features have been recently tested, the tracking set
268 is cleared so the cycle starts fresh.
269
270 Args:
271 batch_size: Maximum number of feature IDs to return (1-5).
272
273 Returns:
274 List of feature IDs to test, may be shorter than batch_size if
275 fewer passing features are available. Empty list if none available.
276 """
277 session = self.get_session()
278 try:
279 session.expire_all()
280 passing = (
281 session.query(Feature)
282 .filter(Feature.passes == True)
283 .filter(Feature.in_progress == False) # Don't test while coding
284 .all()
285 )
286
287 # Extract data from ORM objects before closing the session to avoid
288 # DetachedInstanceError when accessing attributes after session.close().
289 passing_data: list[dict] = []
290 for f in passing:
291 passing_data.append({
292 'id': f.id,
293 'dependencies': f.get_dependencies_safe() if hasattr(f, 'get_dependencies_safe') else [],
294 })
295 finally:
296 session.close()
297
298 if not passing_data:
299 return []
300
301 # Build a reverse dependency map: feature_id -> count of features that depend on it.
302 # The Feature model stores dependencies (what I depend ON), so we invert to find
303 # dependents (what depends ON me).
304 dependent_counts: dict[int, int] = {}
305 for fd in passing_data:
306 for dep_id in fd['dependencies']:
307 dependent_counts[dep_id] = dependent_counts.get(dep_id, 0) + 1
308
309 # Exclude features that are already being tested by running testing agents
310 # to avoid redundant concurrent testing of the same features.
311 # running_testing_agents is dict[pid, (primary_feature_id, process)]
312 with self._lock:
313 currently_testing_ids: set[int] = set()
314 for _pid, (feat_id, _proc) in self.running_testing_agents.items():
315 currently_testing_ids.add(feat_id)
316

Callers 1

_spawn_testing_agentMethod · 0.95

Calls 4

get_sessionMethod · 0.95
get_dependencies_safeMethod · 0.80
logMethod · 0.80
closeMethod · 0.45

Tested by

no test coverage detected