@@ -603,6 +603,8 @@ fn test(skip_deploy: bool) -> Result<()> {
603603 }
604604 } ;
605605
606+ let log_streams = stream_logs ( & cfg. cluster . url ( ) ) ?;
607+
606608 // Run the tests.
607609 if let Err ( e) = std:: process:: Command :: new ( "mocha" )
608610 . arg ( "-t" )
@@ -622,6 +624,10 @@ fn test(skip_deploy: bool) -> Result<()> {
622624 validator_handle. kill ( ) ?;
623625 }
624626
627+ for mut stream in log_streams {
628+ stream. kill ( ) ?;
629+ }
630+
625631 Ok ( ( ) )
626632 } )
627633}
@@ -652,6 +658,38 @@ fn genesis_flags() -> Result<Vec<String>> {
652658 Ok ( flags)
653659}
654660
661+ fn stream_logs ( url : & str ) -> Result < Vec < std:: process:: Child > > {
662+ let program_logs_dir = ".anchor/program-logs" ;
663+ if Path :: new ( program_logs_dir) . exists ( ) {
664+ std:: fs:: remove_dir_all ( program_logs_dir) ?;
665+ }
666+ fs:: create_dir_all ( program_logs_dir) ?;
667+ let mut handles = vec ! [ ] ;
668+ for program in read_all_programs ( ) ? {
669+ let mut file = File :: open ( & format ! ( "target/idl/{}.json" , program. lib_name) ) ?;
670+ let mut contents = vec ! [ ] ;
671+ file. read_to_end ( & mut contents) ?;
672+ let idl: Idl = serde_json:: from_slice ( & contents) ?;
673+ let metadata = idl. metadata . ok_or ( anyhow ! ( "Program address not found." ) ) ?;
674+ let metadata: IdlTestMetadata = serde_json:: from_value ( metadata) ?;
675+
676+ let log_file = File :: create ( format ! (
677+ "{}/{}.{}.log" ,
678+ program_logs_dir, metadata. address, program. idl. name
679+ ) ) ?;
680+ let stdio = std:: process:: Stdio :: from ( log_file) ;
681+ let child = std:: process:: Command :: new ( "solana" )
682+ . arg ( "logs" )
683+ . arg ( metadata. address )
684+ . arg ( "--url" )
685+ . arg ( url)
686+ . stdout ( stdio)
687+ . spawn ( ) ?;
688+ handles. push ( child) ;
689+ }
690+ Ok ( handles)
691+ }
692+
655693#[ derive( Debug , Serialize , Deserialize ) ]
656694pub struct IdlTestMetadata {
657695 address : String ,
0 commit comments