Skip to content

Commit d49a369

Browse files
committed
test(perf): add block latency test
fio emits latency metrics regarding how much time was spent inside the guest operating system (submission latency, slat) or how much time was spent in the device (clat). For firecracker, the latter could be relevant, so emit them from the block performance tests. Signed-off-by: Patrick Roy <[email protected]>
1 parent 5898e0e commit d49a369

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

tests/integration_tests/performance/test_block_ab.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""Performance benchmark for block device emulation."""
44

55
import concurrent
6+
import glob
67
import os
78
import shutil
89
from pathlib import Path
@@ -68,6 +69,7 @@ def run_fio(microvm, mode, block_size):
6869
# Instruct fio to pin one worker per vcpu
6970
.with_arg("--cpus_allowed_policy=split")
7071
.with_arg(f"--write_bw_log={mode}")
72+
.with_arg(f"--write_lat_log={mode}")
7173
.with_arg("--log_avg_msec=1000")
7274
.build()
7375
)
@@ -101,37 +103,51 @@ def run_fio(microvm, mode, block_size):
101103
return logs_path, cpu_load_future.result()
102104

103105

104-
def process_fio_logs(vm, fio_mode, logs_dir, metrics):
105-
"""Parses the fio logs in `{logs_dir}/{fio_mode}_bw.*.log and emits their contents as CloudWatch metrics"""
106-
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"""
107108
data = [
108-
Path(f"{logs_dir}/{fio_mode}_bw.{job_id + 1}.log")
109-
.read_text("UTF-8")
110-
.splitlines()
111-
for job_id in range(vm.vcpus_count)
109+
Path(pathname).read_text("UTF-8").splitlines()
110+
for pathname in glob.glob(logs_glob)
112111
]
113112

113+
assert data, "no log files found!"
114+
114115
for tup in zip(*data):
115-
bw_read = 0
116-
bw_write = 0
116+
read_values = []
117+
write_values = []
117118

118119
for line in tup:
120+
# See https://fio.readthedocs.io/en/latest/fio_doc.html#log-file-formats
119121
_, value, direction, _ = line.split(",", maxsplit=3)
120122
value = int(value.strip())
121123

122-
# See https://fio.readthedocs.io/en/latest/fio_doc.html#log-file-formats
123124
match direction.strip():
124125
case "0":
125-
bw_read += value
126+
read_values.append(value)
126127
case "1":
127-
bw_write += value
128+
write_values.append(value)
128129
case _:
129130
assert False
130131

132+
yield read_values, write_values
133+
134+
135+
def emit_fio_metrics(logs_dir, metrics):
136+
"""Parses the fio logs in `{logs_dir}/*_[bw|lat].*.log and emits their contents as CloudWatch metrics"""
137+
138+
for bw_read, bw_write in process_fio_log_files(f"{logs_dir}/*_bw.*.log"):
131139
if bw_read:
132-
metrics.put_metric("bw_read", bw_read, "Kilobytes/Second")
140+
metrics.put_metric("bw_read", sum(bw_read), "Kilobytes/Second")
133141
if bw_write:
134-
metrics.put_metric("bw_write", bw_write, "Kilobytes/Second")
142+
metrics.put_metric("bw_write", sum(bw_write), "Kilobytes/Second")
143+
144+
for lat_read, lat_write in process_fio_log_files(f"{logs_dir}/*_clat.*.log"):
145+
# latency values in fio logs are in nanosecons, but cloudwatch only supports
146+
# microseconds as the more granular unit, so need to divide by 1000.
147+
for value in lat_read:
148+
metrics.put_metric("clat_read", value / 1000, "Microseconds")
149+
for value in lat_write:
150+
metrics.put_metric("clat_write", value / 1000, "Microseconds")
135151

136152

137153
@pytest.mark.timeout(120)
@@ -177,7 +193,7 @@ def test_block_performance(
177193

178194
logs_dir, cpu_util = run_fio(vm, fio_mode, fio_block_size)
179195

180-
process_fio_logs(vm, fio_mode, logs_dir, metrics)
196+
emit_fio_metrics(logs_dir, metrics)
181197

182198
for thread_name, values in cpu_util.items():
183199
for value in values:
@@ -226,7 +242,7 @@ def test_block_vhost_user_performance(
226242

227243
logs_dir, cpu_util = run_fio(vm, fio_mode, fio_block_size)
228244

229-
process_fio_logs(vm, fio_mode, logs_dir, metrics)
245+
emit_fio_metrics(logs_dir, metrics)
230246

231247
for thread_name, values in cpu_util.items():
232248
for value in values:

0 commit comments

Comments
 (0)