7
7
import subprocess
8
8
import tempfile
9
9
import platform
10
+ import sys
10
11
11
12
import time
12
13
from subprocess import PIPE
@@ -225,7 +226,24 @@ def run_cmd_inside_vm(cmd, vmm_process, prompt, timeout=5):
225
226
226
227
Note: `cmd` and `prompt` should be a `bytes` object and not `str`.
227
228
"""
228
- cmd = cmd .strip () + b'\r \n '
229
+ cmd = cmd .strip ()
230
+
231
+ # The max capacity of the buffer for serial console is 64.(https://github.com/rust-vmm/vm-superio/blob/282bae92878936086606715412494fa81151efba/crates/vm-superio/src/serial.rs#L34)
232
+ # So we split the command at 63 bytes. 1 extra is reserved for \r at the end.
233
+ # empty string is of size 33. sys.getsizeof(b'') = 33.
234
+ # 63-33 = 30. So we add at max 30 [0-29] chars inside the command buffer.
235
+ break_at = 30
236
+ size = sys .getsizeof (cmd )
237
+ while size >= 64 :
238
+ cmd_i = cmd [:break_at ]
239
+
240
+ vmm_process .stdin .write (cmd_i )
241
+ vmm_process .stdin .flush ()
242
+ time .sleep (1 )
243
+ cmd = cmd [break_at :]
244
+ size = sys .getsizeof (cmd )
245
+
246
+ cmd = cmd + b'\r \n '
229
247
230
248
vmm_process .stdin .write (cmd )
231
249
vmm_process .stdin .flush ()
@@ -433,17 +451,17 @@ def test_reference_vmm_with_net_device(kernel , disk):
433
451
"""Start the reference VMM and verify the tap device."""
434
452
435
453
prompt = "root@ubuntu-rust-vmm:~#"
436
- # These are defults values for net
437
- # device.
454
+ # These are defults values for net devices.
438
455
tap_device = "tap0"
439
456
guest_ip = "172.16.0.2"
440
457
host_ip = "172.16.0.1"
441
458
mask = 24
442
459
guest_ip_with_mask = f"{ guest_ip } /{ mask } "
443
- try :
444
- setup_host ()
445
460
446
- vmm_process , _ = start_vmm_process (kernel , disk_path = disk ,tap_device = tap_device )
461
+ setup_host ()
462
+
463
+ try :
464
+ vmm_process , temp_file_path = start_vmm_process (kernel , disk_path = disk ,tap_device = tap_device )
447
465
448
466
setup_guest (vmm_process , prompt )
449
467
@@ -460,43 +478,35 @@ def test_reference_vmm_with_net_device(kernel , disk):
460
478
461
479
finally :
462
480
shutdown (vmm_process )
481
+ if temp_file_path :
482
+ os .remove (temp_file_path )
483
+
484
+ # we will always clear the tap device no matter if the
485
+ # test passes or fails.
463
486
clean_tap ()
464
487
465
488
466
489
def setup_guest (vmm_process , prompt , guest_ip_with_mask = "172.16.0.2/24" , host_ip = "172.16.0.1" ):
467
490
"""Configure the guest vm with the tap device"""
491
+
492
+ # To clear the inital stdout which was printed while
493
+ # booting the vmm.
468
494
expect_string (vmm_process ,prompt )
469
- # This is a little hack to write the command in chunks
470
- # because there is a character limit. `i_` represents
471
- # an incomplete command.
472
- i_add_addr1_cmd = "i_ip addr add "
473
- i_add_addr2_cmd = f"i_{ guest_ip_with_mask } "
474
- add_addr3_cmd = "dev eth0"
495
+
496
+ add_addr_cmd = f"ip addr add { guest_ip_with_mask } dev eth0"
475
497
interface_up_cmd = "ip link set eth0 up"
476
- i_add_route1_cmd = "i_ip route add default "
477
- i_add_route2_cmd = f"i_via { host_ip } "
478
- add_route3_cmd = "dev eth0"
498
+ add_route_cmd = f"ip route add default via { host_ip } dev eth0"
479
499
show_interface_cmd = "ip a"
480
500
481
- all_cmds = [i_add_addr1_cmd , i_add_addr2_cmd , add_addr3_cmd , interface_up_cmd , i_add_route1_cmd , i_add_route2_cmd , add_route3_cmd ]
501
+ all_cmds = [add_addr_cmd , interface_up_cmd , add_route_cmd ]
482
502
483
503
for cmd in all_cmds :
484
- in_between = cmd [:2 ] == "i_"
485
- if in_between :
486
- cmd = cmd [2 :]
487
- cmd = cmd .encode ()
488
- else :
489
- cmd = cmd .encode ().strip () + b'\r \n '
490
- vmm_process .stdin .write (cmd )
491
- vmm_process .stdin .flush ()
492
- time .sleep (1 )
493
-
494
- # just to flush out any data on stdout
495
- os .read (vmm_process .stdout .fileno (), 4096 )
496
-
504
+ _ = run_cmd_inside_vm (cmd .encode () , vmm_process , prompt .encode ())
505
+
497
506
# verifying that guest interface is setup properly
498
507
output = run_cmd_inside_vm (show_interface_cmd .encode () , vmm_process ,prompt .encode () , timeout = 10 )
499
508
output = b'' .join (output ).decode ()
509
+
500
510
assert output .find (f"inet { guest_ip_with_mask } scope global eth0" ) != - 1
501
511
502
512
def setup_host (tap_device = "tap0" , host_ip_with_mask = "172.16.0.1/24" ):
0 commit comments