@@ -598,8 +598,9 @@ impl AppCore {
598598 where
599599 F : Fn ( & NodeDefinition , & HealthSummary ) -> HealthSummary ,
600600 {
601- let _run = self . full_node_test_lock . lock ( ) ;
602- * self . full_node_test_result . lock ( ) = None ;
601+ let Some ( _run) = self . full_node_test_lock . try_lock ( ) else {
602+ return Ok ( FailoverOutcome :: Skipped ) ;
603+ } ;
603604
604605 let before = self . settings ( ) ?;
605606 if !before. acceleration_enabled
@@ -608,6 +609,7 @@ impl AppCore {
608609 {
609610 return Ok ( FailoverOutcome :: Skipped ) ;
610611 }
612+ * self . full_node_test_result . lock ( ) = None ;
611613 let from = self
612614 . nodes ( ) ?
613615 . into_iter ( )
@@ -3115,6 +3117,7 @@ mod tests {
31153117 "https://second.example/https://github.com/" ,
31163118 ) ;
31173119 configure_automatic_nodes ( & core, & [ first. clone ( ) , second. clone ( ) ] , & first. id ) ;
3120+ * core. full_node_test_result . lock ( ) = Some ( Err ( "stale result" . into ( ) ) ) ;
31183121
31193122 let outcome = core
31203123 . recheck_failed_node_with ( & first. id , |_, previous| HealthSummary {
@@ -3135,6 +3138,7 @@ mod tests {
31353138 to: "Second" . into( )
31363139 }
31373140 ) ;
3141+ assert ! ( core. full_node_test_result. lock( ) . is_none( ) ) ;
31383142 let settings = core. settings ( ) . unwrap ( ) ;
31393143 assert_eq ! ( settings. current_node_id. as_deref( ) , Some ( "second" ) ) ;
31403144 assert ! ( settings. acceleration_enabled) ;
@@ -3258,6 +3262,34 @@ mod tests {
32583262 ) ;
32593263 }
32603264
3265+ #[ test]
3266+ fn failed_node_recheck_skips_without_clearing_results_while_a_test_is_running ( ) {
3267+ let directory = tempfile:: tempdir ( ) . unwrap ( ) ;
3268+ let core = AppCore :: new ( directory. path ( ) . to_path_buf ( ) ) . unwrap ( ) ;
3269+ let node = custom_node (
3270+ "current" ,
3271+ "Current" ,
3272+ "https://current.example/https://github.com/" ,
3273+ ) ;
3274+ configure_automatic_nodes ( & core, std:: slice:: from_ref ( & node) , & node. id ) ;
3275+ * core. full_node_test_result . lock ( ) = Some ( Err ( "existing result" . into ( ) ) ) ;
3276+ let active = core. full_node_test_lock . lock ( ) ;
3277+
3278+ let outcome = core
3279+ . recheck_failed_node_with ( & node. id , |_, _| {
3280+ panic ! ( "recheck must not probe while another node test is running" )
3281+ } )
3282+ . unwrap ( ) ;
3283+
3284+ assert_eq ! ( outcome, FailoverOutcome :: Skipped ) ;
3285+ assert ! ( core
3286+ . full_node_test_result
3287+ . lock( )
3288+ . as_ref( )
3289+ . is_some_and( |result| result. as_ref( ) . unwrap_err( ) == "existing result" ) ) ;
3290+ drop ( active) ;
3291+ }
3292+
32613293 #[ test]
32623294 fn real_git_recheck_falls_back_to_direct_when_no_node_is_usable ( ) {
32633295 const MARKER : & str = "GITBOOST_REAL_FAILURE_RECHECK_CHILD" ;
0 commit comments