@@ -85,6 +85,7 @@ def test_tx_rate_limiting(test_microvm_with_ssh, network_config):
8585 test_microvm .start ()
8686
8787 _check_tx_rate_limiting (test_microvm , guest_ips , host_ips )
88+ _check_tx_rate_limit_patch (test_microvm , guest_ips , host_ips )
8889
8990
9091def test_rx_rate_limiting (test_microvm_with_ssh , network_config ):
@@ -145,6 +146,7 @@ def test_rx_rate_limiting(test_microvm_with_ssh, network_config):
145146 test_microvm .start ()
146147
147148 _check_rx_rate_limiting (test_microvm , guest_ips )
149+ _check_rx_rate_limit_patch (test_microvm , guest_ips )
148150
149151
150152def _check_tx_rate_limiting (test_microvm , guest_ips , host_ips ):
@@ -336,6 +338,103 @@ def _check_rx_rate_limiting(test_microvm, guest_ips):
336338 )
337339
338340
341+ def _check_tx_rate_limit_patch (test_microvm , guest_ips , host_ips ):
342+ """Patch the TX rate limiters and check the new limits."""
343+ bucket_size = int (RATE_LIMIT_BYTES / 2 )
344+ bandwidth_kb = int (bucket_size / (RATE_LIMIT_REFILL_TIME / 1000.0 ) / 1024 )
345+
346+ # Check that a TX rate limiter can be applied to a previously unlimited
347+ # interface.
348+ _patch_iface_bw (test_microvm , "1" , "TX" , bucket_size )
349+ _check_tx_bandwidth (test_microvm , guest_ips [0 ], host_ips [0 ], bandwidth_kb )
350+
351+ # Check that a TX rate limiter can be updated.
352+ _patch_iface_bw (test_microvm , "2" , "TX" , bucket_size )
353+ _check_tx_bandwidth (test_microvm , guest_ips [1 ], host_ips [1 ], bandwidth_kb )
354+
355+
356+ def _check_rx_rate_limit_patch (test_microvm , guest_ips ):
357+ """Patch the RX rate limiters and check the new limits."""
358+ bucket_size = int (RATE_LIMIT_BYTES / 2 )
359+ bandwidth_kb = int (bucket_size / (RATE_LIMIT_REFILL_TIME / 1000.0 ) / 1024 )
360+
361+ # Check that an RX rate limiter can be applied to a previously unlimited
362+ # interface.
363+ _patch_iface_bw (test_microvm , "1" , "RX" , bucket_size )
364+ _check_rx_bandwidth (test_microvm , guest_ips [0 ], bandwidth_kb )
365+
366+ # Check that an RX rate limiter can be updated.
367+ _patch_iface_bw (test_microvm , "2" , "RX" , bucket_size )
368+ _check_rx_bandwidth (test_microvm , guest_ips [1 ], bandwidth_kb )
369+
370+
371+ def _check_tx_bandwidth (
372+ test_microvm ,
373+ guest_ip ,
374+ host_ip ,
375+ expected_bw_kb
376+ ):
377+ """Check that the rate-limited TX bandwidth is close to what we expect.
378+
379+ At this point, a daemonized iperf3 server is expected to be running on
380+ the host.
381+ """
382+ iperf_cmd = "{} -c {} -t {} -f KBytes" .format (
383+ IPERF_BINARY ,
384+ host_ip ,
385+ IPERF_TRANSMIT_TIME
386+ )
387+
388+ iperf_out = _run_iperf_on_guest (test_microvm , iperf_cmd , guest_ip )
389+ _ , observed_bw = _process_iperf_output (iperf_out )
390+
391+ diff_pc = _get_difference (observed_bw , expected_bw_kb )
392+ assert diff_pc < MAX_BYTES_DIFF_PERCENTAGE
393+
394+
395+ def _check_rx_bandwidth (
396+ test_microvm ,
397+ guest_ip ,
398+ expected_bw_kb
399+ ):
400+ """Check that the rate-limited RX bandwidth is close to what we expect.
401+
402+ At this point, a daemonized iperf3 server is expected to be running on
403+ the guest.
404+ """
405+ iperf_cmd = "{} {} -c {} -t {} -f KBytes" .format (
406+ test_microvm .jailer .netns_cmd_prefix (),
407+ IPERF_BINARY ,
408+ guest_ip ,
409+ IPERF_TRANSMIT_TIME
410+ )
411+ iperf_out = _run_local_iperf (iperf_cmd )
412+ _ , observed_bw = _process_iperf_output (iperf_out )
413+
414+ diff_pc = _get_difference (observed_bw , expected_bw_kb )
415+ assert diff_pc < MAX_BYTES_DIFF_PERCENTAGE
416+
417+
418+ def _patch_iface_bw (test_microvm , iface_id , rx_or_tx , new_bucket_size ):
419+ """Update the bandwidth rate limiter for a given interface.
420+
421+ Update the `rx_or_tx` rate limiter, on interface `iface_id` to the
422+ new `bucket_size`.
423+ """
424+ assert rx_or_tx in ['RX' , 'TX' ]
425+ args = {
426+ 'iface_id' : iface_id ,
427+ "{}_rate_limiter" .format (rx_or_tx .lower ()): {
428+ 'bandwidth' : {
429+ 'size' : new_bucket_size ,
430+ 'refill_time' : RATE_LIMIT_REFILL_TIME
431+ }
432+ }
433+ }
434+ resp = test_microvm .network .patch (** args )
435+ assert test_microvm .api_session .is_status_no_content (resp .status_code )
436+
437+
339438def _start_iperf_on_guest (test_microvm , hostname ):
340439 """Start iperf in server mode through an SSH connection."""
341440 test_microvm .ssh_config ['hostname' ] = hostname
0 commit comments