@@ -275,6 +275,7 @@ impl net_backend::Endpoint for TestNicEndpoint {
275
275
}
276
276
277
277
async fn set_data_path_to_guest_vf ( & self , use_vf : bool ) -> anyhow:: Result < ( ) > {
278
+ tracing:: info!( use_vf, "set_data_path_to_guest_vf" ) ;
278
279
let inner = self . inner . clone ( ) ;
279
280
let mut iter = {
280
281
let locked_inner = inner. lock ( ) . await ;
@@ -657,14 +658,17 @@ impl TestNicDevice {
657
658
658
659
pub async fn retarget_vp ( & self , vp : u32 ) {
659
660
let modify_request = ModifyRequest :: TargetVp { target_vp : vp } ;
660
- let modify_response = self
661
- . send_to_channel (
662
- 0 ,
663
- ChannelRequest :: Modify ,
664
- modify_request,
665
- ChannelResponse :: Modify ,
666
- )
661
+ let send_request = self . send_to_channel (
662
+ 0 ,
663
+ ChannelRequest :: Modify ,
664
+ modify_request,
665
+ ChannelResponse :: Modify ,
666
+ ) ;
667
+ let modify_response = mesh:: CancelContext :: new ( )
668
+ . with_timeout ( Duration :: from_millis ( 333 ) )
669
+ . until_cancelled ( send_request)
667
670
. await
671
+ . expect ( "response received" )
668
672
. expect ( "modify successful" ) ;
669
673
670
674
assert ! ( matches!( modify_response, ChannelResponse :: Modify ( 0 ) ) ) ;
@@ -1493,6 +1497,13 @@ impl VirtualFunction for TestVirtualFunction {
1493
1497
self . state . id ( )
1494
1498
}
1495
1499
async fn guest_ready_for_device ( & mut self ) {
1500
+ // Wait a random amount of time before completing the request.
1501
+ let mut wait_ms: u64 = 0 ;
1502
+ getrandom:: fill ( wait_ms. as_mut_bytes ( ) ) . expect ( "rng failure" ) ;
1503
+ wait_ms %= 50 ;
1504
+ tracing:: info!( id = self . state. id( ) , wait_ms, "Readying VF..." ) ;
1505
+ let mut ctx = mesh:: CancelContext :: new ( ) . with_timeout ( Duration :: from_millis ( wait_ms) ) ;
1506
+ let _ = ctx. until_cancelled ( pending :: < ( ) > ( ) ) . await ;
1496
1507
tracing:: info!( id = self . state. id( ) , "VF ready" ) ;
1497
1508
self . state . set_ready ( true ) . await ;
1498
1509
}
@@ -2538,7 +2549,7 @@ async fn stop_start_with_vf(driver: DefaultDriver) {
2538
2549
// 'guest VF' state logic.
2539
2550
assert ! (
2540
2551
test_vf_state
2541
- . await_ready( true , Duration :: ZERO )
2552
+ . await_ready( true , Duration :: from_millis ( 333 ) )
2542
2553
. await
2543
2554
. is_ok( )
2544
2555
) ;
@@ -4640,6 +4651,22 @@ async fn race_coordinator_and_worker_stop_events(driver: DefaultDriver) {
4640
4651
} else {
4641
4652
false
4642
4653
} ;
4654
+ // Change the VF availability every other instance.
4655
+ if ( i % 2 ) == 0 {
4656
+ let is_add = ( i % 4 ) == 0 ;
4657
+ test_vf_state
4658
+ . update_id (
4659
+ if is_add { Some ( 124 ) } else { None } ,
4660
+ Some ( Duration :: from_millis ( 100 ) ) ,
4661
+ )
4662
+ . await
4663
+ . unwrap ( ) ;
4664
+
4665
+ if is_add {
4666
+ PolledTimer :: new ( & driver) . sleep ( VF_DEVICE_DELAY ) . await ;
4667
+ }
4668
+ }
4669
+
4643
4670
// send switch data path message
4644
4671
channel
4645
4672
. write ( OutgoingPacket {
@@ -4672,6 +4699,7 @@ async fn race_coordinator_and_worker_stop_events(driver: DefaultDriver) {
4672
4699
)
4673
4700
. await ;
4674
4701
}
4702
+
4675
4703
// Trigger a retarget VP 2/3 of the time offset with the link update,
4676
4704
// such that 1/3 times only link update or retarget VP will be
4677
4705
// triggered.
@@ -4690,14 +4718,44 @@ async fn race_coordinator_and_worker_stop_events(driver: DefaultDriver) {
4690
4718
. read_with ( |packet| match packet {
4691
4719
IncomingPacket :: Completion ( _) => None ,
4692
4720
IncomingPacket :: Data ( data) => {
4693
- let ( rndis_header, _) = rndis_parser. parse_control_message ( data) ;
4694
- if rndis_header. message_type == rndisprot:: MESSAGE_TYPE_KEEPALIVE_CMPLT {
4695
- tracing:: info!( "Got keepalive completion" ) ;
4696
- Some ( data. transaction_id ( ) . expect ( "should request completion" ) )
4697
- } else {
4698
- tracing:: info!( rndis_header. message_type, "Got link status update" ) ;
4699
- Some ( data. transaction_id ( ) . expect ( "should request completion" ) )
4721
+ let mut reader = data. reader ( ) ;
4722
+ let header: protocol:: MessageHeader = reader. read_plain ( ) . unwrap ( ) ;
4723
+ match header. message_type {
4724
+ protocol:: MESSAGE4_TYPE_SEND_VF_ASSOCIATION => {
4725
+ let association_data: protocol:: Message4SendVfAssociation =
4726
+ reader. read_plain ( ) . unwrap ( ) ;
4727
+ tracing:: info!(
4728
+ is_vf = association_data. vf_allocated,
4729
+ vfid = association_data. serial_number,
4730
+ "Message: VF association"
4731
+ ) ;
4732
+ }
4733
+ protocol:: MESSAGE4_TYPE_SWITCH_DATA_PATH => {
4734
+ tracing:: info!( "Message: switch data path" ) ;
4735
+ let switch_result: protocol:: Message4SwitchDataPath =
4736
+ reader. read_plain ( ) . unwrap ( ) ;
4737
+ // Switch data path is expected when the data
4738
+ // path is forced to synthetic.
4739
+ assert_eq ! (
4740
+ switch_result. active_data_path,
4741
+ protocol:: DataPath :: SYNTHETIC . 0
4742
+ ) ;
4743
+ }
4744
+ _ => {
4745
+ let ( rndis_header, _) = rndis_parser. parse_control_message ( data) ;
4746
+ if rndis_header. message_type
4747
+ == rndisprot:: MESSAGE_TYPE_KEEPALIVE_CMPLT
4748
+ {
4749
+ tracing:: info!( "Message: keepalive completion" ) ;
4750
+ } else {
4751
+ tracing:: info!(
4752
+ rndis_header. message_type,
4753
+ "Message: link status update"
4754
+ ) ;
4755
+ }
4756
+ }
4700
4757
}
4758
+ Some ( data. transaction_id ( ) . expect ( "should request completion" ) )
4701
4759
}
4702
4760
} )
4703
4761
. await
0 commit comments