@@ -419,6 +419,7 @@ async fn parse_multipart(boundary: String, body: Vec<u8>) -> anyhow::Result<Vec<
419419#[ cfg( test) ]
420420mod tests {
421421 use super :: * ;
422+ use rusty_fork:: rusty_fork_test;
422423
423424 #[ test]
424425 fn test_temp_file_guard_and_path_generation ( ) {
@@ -515,52 +516,58 @@ mod tests {
515516 assert_eq ! ( parsed. multipart_parts[ 0 ] . content, b"value" ) ;
516517 }
517518
518- #[ test]
519- #[ cfg_attr( miri, ignore) ]
520- fn test_count_active_threads ( ) {
521- let initial_count = count_active_threads ( ) . expect ( "Failed to count threads" ) ;
522- assert ! (
523- initial_count >= 1 ,
524- "Expected at least 1 thread, got {}" ,
525- initial_count
526- ) ;
527-
528- // Spawn some threads and verify the count increases
529- use std:: sync:: { Arc , Barrier } ;
530- let barrier = Arc :: new ( Barrier :: new ( 6 ) ) ; // 5 spawned threads + main thread
531-
532- let handles: Vec < _ > = ( 0 ..5 )
533- . map ( |_| {
534- let barrier = Arc :: clone ( & barrier) ;
535- std:: thread:: spawn ( move || {
536- barrier. wait ( ) ;
537- std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
519+ // This test must run in its own process to get accurate thread counts,
520+ // since the test runner and other parallel tests spawn threads.
521+ rusty_fork_test ! {
522+ #[ test]
523+ #[ cfg_attr( miri, ignore) ]
524+ fn test_count_active_threads( ) {
525+ use crate :: test_utils:: count_active_threads;
526+
527+ let initial_count = count_active_threads( ) . expect( "Failed to count threads" ) ;
528+ assert!(
529+ initial_count >= 1 ,
530+ "Expected at least 1 thread, got {}" ,
531+ initial_count
532+ ) ;
533+
534+ // Spawn some threads and verify the count increases
535+ use std:: sync:: { Arc , Barrier } ;
536+ let barrier = Arc :: new( Barrier :: new( 6 ) ) ; // 5 spawned threads + main thread
537+
538+ let handles: Vec <_> = ( 0 ..5 )
539+ . map( |_| {
540+ let barrier = Arc :: clone( & barrier) ;
541+ std:: thread:: spawn( move || {
542+ barrier. wait( ) ;
543+ std:: thread:: sleep( std:: time:: Duration :: from_millis( 50 ) ) ;
544+ } )
538545 } )
539- } )
540- . collect ( ) ;
541-
542- barrier. wait ( ) ;
543- let count_with_threads = count_active_threads ( ) . expect ( "Failed to count threads" ) ;
544- assert ! (
545- count_with_threads >= initial_count + 5 ,
546- "Expected at least {} threads (initial: {}, with 5 spawned: {})" ,
547- initial_count + 5 ,
548- initial_count,
549- count_with_threads
550- ) ;
546+ . collect( ) ;
547+
548+ barrier. wait( ) ;
549+ let count_with_threads = count_active_threads( ) . expect( "Failed to count threads" ) ;
550+ assert!(
551+ count_with_threads >= initial_count + 5 ,
552+ "Expected at least {} threads (initial: {}, with 5 spawned: {})" ,
553+ initial_count + 5 ,
554+ initial_count,
555+ count_with_threads
556+ ) ;
557+
558+ for handle in handles {
559+ handle. join( ) . expect( "Thread should join successfully" ) ;
560+ }
551561
552- for handle in handles {
553- handle. join ( ) . expect ( "Thread should join successfully" ) ;
562+ let count_after_join = count_active_threads( ) . expect( "Failed to count threads" ) ;
563+ // Allow up to 1 extra: some platforms (e.g. CentOS 7) lazily spawn a helper thread
564+ assert!(
565+ count_after_join <= initial_count + 1 ,
566+ "Expected thread count to return to {} or {} after join, got {}" ,
567+ initial_count,
568+ initial_count + 1 ,
569+ count_after_join
570+ ) ;
554571 }
555-
556- let count_after_join = count_active_threads ( ) . expect ( "Failed to count threads" ) ;
557- // Allow up to 1 extra: some platforms (e.g. CentOS 7) lazily spawn a helper thread
558- assert ! (
559- count_after_join <= initial_count + 1 ,
560- "Expected thread count to return to {} or {} after join, got {}" ,
561- initial_count,
562- initial_count + 1 ,
563- count_after_join
564- ) ;
565572 }
566573}
0 commit comments