55import  concurrent 
66import  glob 
77import  os 
8- import  shutil 
98from  pathlib  import  Path 
109
1110import  pytest 
@@ -45,7 +44,7 @@ def prepare_microvm_for_test(microvm):
4544    check_output ("echo 3 > /proc/sys/vm/drop_caches" )
4645
4746
48- def  run_fio (microvm , mode , block_size , fio_engine = "libaio" ):
47+ def  run_fio (microvm , mode , block_size , test_output_dir ,  fio_engine = "libaio" ):
4948    """Run a fio test in the specified mode with block size bs.""" 
5049    cmd  =  (
5150        CmdBuilder ("fio" )
@@ -71,16 +70,11 @@ def run_fio(microvm, mode, block_size, fio_engine="libaio"):
7170        .with_arg (f"--write_bw_log={ mode }  " )
7271        .with_arg (f"--write_lat_log={ mode }  " )
7372        .with_arg ("--log_avg_msec=1000" )
73+         .with_arg ("--output-format=json+" )
74+         .with_arg ("--output=/tmp/fio.json" )
7475        .build ()
7576    )
7677
77-     logs_path  =  Path (microvm .jailer .chroot_base_with_id ()) /  "fio_output" 
78- 
79-     if  logs_path .is_dir ():
80-         shutil .rmtree (logs_path )
81- 
82-     logs_path .mkdir ()
83- 
8478    prepare_microvm_for_test (microvm )
8579
8680    # Start the CPU load monitor. 
@@ -97,17 +91,23 @@ def run_fio(microvm, mode, block_size, fio_engine="libaio"):
9791        assert  rc  ==  0 , stderr 
9892        assert  stderr  ==  "" 
9993
100-         microvm .ssh .scp_get ("/tmp/*.log " , logs_path )
101-         microvm .ssh .check_output ( "rm  /tmp/*.log" )
94+         microvm .ssh .scp_get ("/tmp/fio.json " , test_output_dir )
95+         microvm .ssh .scp_get ( " /tmp/*.log",  test_output_dir )
10296
103-         return  logs_path ,  cpu_load_future .result ()
97+         return  cpu_load_future .result ()
10498
10599
106- def  process_fio_log_files (logs_glob ):
107-     """Parses all fio log files matching the given glob and yields tuples of same-timestamp read and write metrics""" 
100+ def  process_fio_log_files (root_dir , logs_glob ):
101+     """ 
102+     Parses all fio log files in the root_dir matching the given glob and 
103+     yields tuples of same-timestamp read and write metrics 
104+     """ 
105+     # We specify `root_dir` for `glob.glob` because otherwise it will 
106+     # struggle with directory with names like: 
107+     # test_block_performance[vmlinux-5.10.233-Sync-bs4096-randread-1vcpu] 
108108    data  =  [
109-         Path (pathname ).read_text ("UTF-8" ).splitlines ()
110-         for  pathname  in  glob .glob (logs_glob )
109+         Path (root_dir   /   pathname ).read_text ("UTF-8" ).splitlines ()
110+         for  pathname  in  glob .glob (logs_glob ,  root_dir = root_dir )
111111    ]
112112
113113    assert  data , "no log files found!" 
@@ -134,13 +134,13 @@ def process_fio_log_files(logs_glob):
134134
135135def  emit_fio_metrics (logs_dir , metrics ):
136136    """Parses the fio logs in `{logs_dir}/*_[clat|bw].*.log and emits their contents as CloudWatch metrics""" 
137-     for  bw_read , bw_write  in  process_fio_log_files (f" { logs_dir } / *_bw.*.log" ):
137+     for  bw_read , bw_write  in  process_fio_log_files (logs_dir ,  " *_bw.*.log" ):
138138        if  bw_read :
139139            metrics .put_metric ("bw_read" , sum (bw_read ), "Kilobytes/Second" )
140140        if  bw_write :
141141            metrics .put_metric ("bw_write" , sum (bw_write ), "Kilobytes/Second" )
142142
143-     for  lat_read , lat_write  in  process_fio_log_files (f" { logs_dir } / *_clat.*.log" ):
143+     for  lat_read , lat_write  in  process_fio_log_files (logs_dir ,  " *_clat.*.log" ):
144144        # latency values in fio logs are in nanoseconds, but cloudwatch only supports 
145145        # microseconds as the more granular unit, so need to divide by 1000. 
146146        for  value  in  lat_read :
@@ -164,6 +164,7 @@ def test_block_performance(
164164    fio_engine ,
165165    io_engine ,
166166    metrics ,
167+     results_dir ,
167168):
168169    """ 
169170    Execute block device emulation benchmarking scenarios. 
@@ -192,9 +193,9 @@ def test_block_performance(
192193
193194    vm .pin_threads (0 )
194195
195-     logs_dir ,  cpu_util  =  run_fio (vm , fio_mode , fio_block_size , fio_engine )
196+     cpu_util  =  run_fio (vm , fio_mode , fio_block_size ,  results_dir , fio_engine )
196197
197-     emit_fio_metrics (logs_dir , metrics )
198+     emit_fio_metrics (results_dir , metrics )
198199
199200    for  thread_name , values  in  cpu_util .items ():
200201        for  value  in  values :
@@ -213,6 +214,7 @@ def test_block_vhost_user_performance(
213214    fio_mode ,
214215    fio_block_size ,
215216    metrics ,
217+     results_dir ,
216218):
217219    """ 
218220    Execute block device emulation benchmarking scenarios. 
@@ -242,9 +244,9 @@ def test_block_vhost_user_performance(
242244    next_cpu  =  vm .pin_threads (0 )
243245    vm .disks_vhost_user ["scratch" ].pin (next_cpu )
244246
245-     logs_dir ,  cpu_util  =  run_fio (vm , fio_mode , fio_block_size )
247+     cpu_util  =  run_fio (vm , fio_mode , fio_block_size ,  results_dir )
246248
247-     emit_fio_metrics (logs_dir , metrics )
249+     emit_fio_metrics (results_dir , metrics )
248250
249251    for  thread_name , values  in  cpu_util .items ():
250252        for  value  in  values :
0 commit comments