@@ -718,4 +718,96 @@ mod tests {
718718
719719 assert ! ( r. is_ok( ) ) ;
720720 }
721+
722+ #[ test]
723+ fn test_bridge_networking ( ) {
724+ use std:: fs;
725+ use std:: io:: Write ;
726+ use std:: process:: Command ;
727+ cleanup_libvirt_state ( ) ;
728+
729+ //configure host IP since we cant do it from XML for bridge network.
730+ Command :: new ( "sh" )
731+ . arg ( "-c" )
732+ . arg ( "sudo ip addr add 192.168.1.1/24 dev mybr0 ; sudo ip addr add 192.168.2.1/24 dev mybr0" )
733+ . spawn ( )
734+ . expect ( "Failed to set IP address." ) ;
735+
736+ let mut guest_name: [ String ; 2 ] = Default :: default ( ) ;
737+ let mut guest_ip: [ String ; 2 ] = Default :: default ( ) ;
738+
739+ let mut libvirtd = spawn_libvirtd ( ) . unwrap ( ) ;
740+ thread:: sleep ( std:: time:: Duration :: new ( 5 , 0 ) ) ;
741+
742+ for i in 0 ..2 {
743+ let mut disk = UbuntuDiskConfig :: new ( FOCAL_IMAGE_NAME . to_owned ( ) ) ;
744+ let guest = Guest :: new ( & mut disk, KernelType :: RustFw ) ;
745+ let domain_path = guest. create_domain ( VcpuConfig :: default ( ) , DEFAULT_RAM_SIZE ) ;
746+
747+ let mut contents =
748+ fs:: read_to_string ( & domain_path) . expect ( "Something went wrong reading the file" ) ;
749+ contents = contents. replace ( "ethernet" , "bridge" ) ;
750+ contents = contents. replace ( "</source>" , "" ) ;
751+ contents = contents. replace ( "source><ip " , "source bridge=\" mybr0\" " ) ;
752+
753+ let mut f = std:: fs:: File :: create ( & domain_path) . unwrap ( ) ;
754+ f. write_all ( contents. as_bytes ( ) ) . unwrap ( ) ;
755+
756+ let r = std:: panic:: catch_unwind ( || {
757+ spawn_virsh ( & [ "create" , domain_path. to_str ( ) . unwrap ( ) ] )
758+ . unwrap ( )
759+ . wait ( )
760+ . unwrap ( ) ;
761+ guest. wait_vm_boot ( None ) . unwrap ( ) ;
762+ } ) ;
763+
764+ let guestname = & guest. vm_name ;
765+ guest_name[ i] = guestname. to_string ( ) ;
766+ assert ! ( r. is_ok( ) ) ;
767+
768+ guest_ip[ i] = guest
769+ . ssh_command (
770+ "ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\\ ([^ ]*\\ ).*/\\ 1/p;q}'" ,
771+ )
772+ . unwrap ( )
773+ . trim_end ( )
774+ . to_string ( ) ;
775+ }
776+
777+ //ping host to guest vm's
778+ for i in 0 ..2 {
779+ let cmd = format ! (
780+ "ping -c 4 {} " ,
781+ & guest_ip[ i]
782+ ) ;
783+ let out = Command :: new ( "sh" )
784+ . arg ( "-c" )
785+ . arg ( & cmd)
786+ . status ( )
787+ . expect ( "failed to execute ping" ) ;
788+
789+ println ! ( " ssh out is : {:?}" , out. code( ) ) ;
790+ assert ! ( out. code( ) == Some ( 0 ) ) ;
791+ }
792+
793+ for i in 0 ..2 {
794+ spawn_virsh ( & [ "destroy" , & guest_name[ i] ] )
795+ . unwrap ( )
796+ . wait ( )
797+ . unwrap ( ) ;
798+ }
799+ libvirtd. kill ( ) . unwrap ( ) ;
800+ let libvirtd_output = libvirtd. wait_with_output ( ) . unwrap ( ) ;
801+ //Cleanup bridge configuration
802+ Command :: new ( "sh" )
803+ . arg ( "-c" )
804+ . arg ( "sudo ip addr del 192.168.1.1/24 dev mybr0 ; sudo ip addr del 192.168.2.1/24 dev mybr0" )
805+ . spawn ( )
806+ . expect ( "Failed to clean IP address." ) ;
807+ eprintln ! (
808+ "libvirtd stdout\n \n {}\n \n libvirtd stderr\n \n {}" ,
809+ std:: str :: from_utf8( & libvirtd_output. stdout) . unwrap( ) ,
810+ std:: str :: from_utf8( & libvirtd_output. stderr) . unwrap( )
811+ ) ;
812+ }
721813}
0 commit comments