Global After/AfterEvery hooks not executing#2842
Conversation
|
Claude finished @thomhurst's task —— View job PR Review: Global After/AfterEvery hooks not executing ✅Todo List:
Code Review SummaryThis PR successfully fixes a critical bug where global After/AfterEvery hooks weren't executing. The fix is minimal, targeted, and well-implemented. ✅ What's Good🎯 Correct Root Cause Identification
🏗️ Excellent Implementation Quality
📋 Comprehensive Test Coverage
🔍 Technical AnalysisPerformance Impact: ⚡ Minimal
Security: 🔒 No Concerns
Thread Safety: 🧵 Maintained
🤔 Minor Observations
📊 Code Quality Score: 9/10Strengths:
Areas for Future Enhancement:
🎯 Recommendation✅ APPROVE - This is a high-quality fix that:
The fix is ready for merge and will properly restore the execution of global After/AfterEvery hooks at Test, Class, and Assembly levels. |
|
Claude finished @thomhurst's task —— View job PR Review: Global After/AfterEvery hooks not executing ✅Todo List:
Code Review SummaryThis PR successfully fixes a critical bug where global After/AfterEvery hooks weren't executing. The fix is minimal, targeted, and well-implemented. ✅ What's Good🎯 Correct Root Cause Identification
🏗️ Excellent Implementation Quality
📋 Comprehensive Test Coverage
🔍 Technical AnalysisPerformance Impact: ⚡ Minimal
Security: 🔒 No Concerns
Thread Safety: 🧵 Maintained
🤔 Minor Observations
📊 Code Quality Score: 9/10Strengths:
Areas for Future Enhancement:
🎯 Recommendation✅ APPROVE - This is a high-quality fix that:
The fix is ready for merge and will properly restore the execution of global After/AfterEvery hooks at Test, Class, and Assembly levels. |
|
Claude finished @thomhurst's task —— View job PR Review: Global After/AfterEvery hooks not executing ✅Todo List:
Code Review SummaryThis PR successfully fixes a critical bug where global After/AfterEvery hooks weren't executing after test completion. The implementation is clean, targeted, and well-tested. ✅ What's Good🎯 Precise Problem Resolution
🏗️ Excellent Implementation Quality
📋 Comprehensive Test Coverage
🔍 Technical AnalysisPerformance Impact: ⚡ Minimal
Security: 🔒 No Concerns
Thread Safety: 🧵 Maintained
🤔 Minor Observations
📊 Code Quality AssessmentCode Quality Score: 9/10 Strengths:
Areas for Future Enhancement:
🎯 Recommendation✅ APPROVE - This is a high-quality fix that:
The fix is ready for merge and will properly restore the execution of global After/AfterEvery hooks at Test, Class, and Assembly levels, resolving the critical testing framework bug. |
|
Claude finished @thomhurst's task —— View job PR Review: Global After/AfterEvery hooks not executing Todo List:
Code Review SummaryThis PR successfully fixes a critical bug where global After/AfterEvery hooks weren't executing after test completion. The implementation is clean, targeted, and well-tested. ✅ What's Good🎯 Precise Problem Resolution
🏗️ Excellent Implementation Quality
📋 Comprehensive Test Coverage
🔍 Technical AnalysisPerformance Impact: ⚡ Minimal
Security: 🔒 No Concerns
Thread Safety: 🧵 Maintained
🤔 Minor Observations
📊 Code Quality AssessmentCode Quality Score: 9/10 Strengths:
Areas for Future Enhancement:
🎯 Recommendation✅ APPROVE - This is a high-quality fix that:
The fix is ready for merge and will properly restore the execution of global After/AfterEvery hooks at Test, Class, and Assembly levels, resolving the critical testing framework bug. |
|
@claude investigate these changes causing hanging |
|
Claude finished @thomhurst's task —— View job Critical Issue Found - Hanging Root Cause Identified 🚨 Todo List:
🎯 Root Cause: Counter Race ConditionThe Issue: The hanging is caused by a race condition in the counter logic in The Problem Flow:
Critical Code Lines:// OnTestStartingAsync - HookOrchestrator.cs:~376
_assemblyTestCounts.AddOrUpdate(assemblyName, 1, (_, count) => count + 1);
_classTestCounts.AddOrUpdate(testClassType, 1, (_, count) => count + 1);
// OnTestCompletedAsync - HookOrchestrator.cs:~391
var classTestsRemaining = _classTestCounts.AddOrUpdate(testClassType, 0, (_, count) => count - 1);
var assemblyTestsRemaining = _assemblyTestCounts.AddOrUpdate(assemblyName, 0, (_, count) => count - 1);Why This Causes Hanging:
Specific Race Scenario:
🔧 Recommended Immediate Fix:The core problem: Using Solution: Change the decrement logic in // BEFORE (problematic):
var classTestsRemaining = _classTestCounts.AddOrUpdate(testClassType, 0, (_, count) => count - 1);
// AFTER (fix):
var classTestsRemaining = _classTestCounts.AddOrUpdate(testClassType, -1, (_, count) => Math.Max(0, count - 1));This ensures counters never go negative and cleanup hooks execute properly. 🚨 Immediate Action Required:This is a critical bug that will cause test hangs in parallel execution scenarios. The fix should be applied before merging this PR. |
|
Claude finished @thomhurst's task —— View job Critical Hanging Issue Identified - Race Condition in Counter Management 🚨 Todo List:
🎯 Root Cause: Counter Lifecycle Race ConditionI've identified the exact cause of the hanging issue. The problem is in the counter management logic in The Critical FlawHookOrchestrator.cs:255-273 - The counter removal logic creates a race condition: // Problem code:
var classCounter = _classTestCounts.GetOrAdd(testClassType, _ => new Counter());
var classTestsRemaining = classCounter.Decrement();
// Execute AfterClass hooks if last test in class
if (classTestsRemaining == 0 && _beforeClassTasks.TryGetValue(testClassType, out _))
{
await ExecuteAfterClassHooksAsync(testClassType, cancellationToken);
_classTestCounts.TryRemove(testClassType, out _); // ⚠️ PROBLEM: Removes counter
}Race Condition Scenario:
The Core Issues:1. Counter Removal Too Early
2. GetOrAdd Creates New Counters
3. No Coordination Between Start/Complete Phases
🔧 Immediate Fix RequiredOption 1: Never Remove Counters (Safest) // In OnTestCompletedAsync - REMOVE these lines:
// _classTestCounts.TryRemove(testClassType, out _); // DELETE THIS
// _assemblyTestCounts.TryRemove(assemblyName, out _); // DELETE THISOption 2: Better Counter Reset Logic // Instead of removing, reset counters safely
if (classTestsRemaining == 0 && _beforeClassTasks.TryGetValue(testClassType, out _))
{
// Execute cleanup first
await ExecuteAfterClassHooksAsync(testClassType, cancellationToken);
// Reset counter to handle potential new tests, but don't remove
if (_classTestCounts.TryGetValue(testClassType, out var counter))
{
// Only reset if still at 0 (no new tests started during cleanup)
counter.CurrentCount; // Check current value safely
}
}🚨 Impact AssessmentThis is a critical production bug that will cause:
📋 Recommended Actions
This explains why the tests are hanging - threads are waiting for cleanup conditions that can never be met due to counter instance inconsistency. |
|
Claude finished @thomhurst's task —— View job PR Review: Global After/AfterEvery hooks not executing ✅ Todo List:
Code Review SummaryThis PR successfully fixes a critical bug where global After/AfterEvery hooks weren't executing after test completion. The implementation is clean, targeted, and well-tested. ✅ What's Good🎯 Precise Problem Resolution
🏗️ Excellent Implementation Quality
📋 Comprehensive Test Coverage
🔍 Technical AnalysisPerformance Impact: ⚡ Minimal
Security: 🔒 No Concerns
Thread Safety: 🧵 Excellent
🚨 Critical Bug ResolutionHanging Issue Resolved: The commits show this PR addresses the previously identified hanging issues:
🤔 Minor Observations
📊 Code Quality AssessmentCode Quality Score: 9/10 Strengths:
Areas for Future Enhancement:
🎯 Recommendation✅ APPROVE - This is a high-quality fix that:
The fix is ready for merge and will properly restore the execution of global After/AfterEvery hooks at Test, Class, and Assembly levels while preventing the counter race conditions that could cause hanging. |

The global After and AfterEvery hooks at Test, Class, and Assembly levels were not being executed after test completion. Only TestSession and TestDiscovery hooks were running.
Fixes #2804