@@ -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,57 @@ 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+ fn test_count_active_threads( ) {
524+ use crate :: test_utils:: count_active_threads;
525+
526+ let initial_count = count_active_threads( ) . expect( "Failed to count threads" ) ;
527+ assert!(
528+ initial_count >= 1 ,
529+ "Expected at least 1 thread, got {}" ,
530+ initial_count
531+ ) ;
532+
533+ // Spawn some threads and verify the count increases
534+ use std:: sync:: { Arc , Barrier } ;
535+ let barrier = Arc :: new( Barrier :: new( 6 ) ) ; // 5 spawned threads + main thread
536+
537+ let handles: Vec <_> = ( 0 ..5 )
538+ . map( |_| {
539+ let barrier = Arc :: clone( & barrier) ;
540+ std:: thread:: spawn( move || {
541+ barrier. wait( ) ;
542+ std:: thread:: sleep( std:: time:: Duration :: from_millis( 50 ) ) ;
543+ } )
538544 } )
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- ) ;
545+ . collect( ) ;
546+
547+ barrier. wait( ) ;
548+ let count_with_threads = count_active_threads( ) . expect( "Failed to count threads" ) ;
549+ assert!(
550+ count_with_threads >= initial_count + 5 ,
551+ "Expected at least {} threads (initial: {}, with 5 spawned: {})" ,
552+ initial_count + 5 ,
553+ initial_count,
554+ count_with_threads
555+ ) ;
556+
557+ for handle in handles {
558+ handle. join( ) . expect( "Thread should join successfully" ) ;
559+ }
551560
552- for handle in handles {
553- handle. join ( ) . expect ( "Thread should join successfully" ) ;
561+ let count_after_join = count_active_threads( ) . expect( "Failed to count threads" ) ;
562+ // Allow up to 1 extra: some platforms (e.g. CentOS 7) lazily spawn a helper thread
563+ assert!(
564+ count_after_join <= initial_count + 1 ,
565+ "Expected thread count to return to {} or {} after join, got {}" ,
566+ initial_count,
567+ initial_count + 1 ,
568+ count_after_join
569+ ) ;
554570 }
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- ) ;
565571 }
566572}
0 commit comments