Skip to content

Commit be2f41a

Browse files
roypatzulinx86
authored andcommitted
test: Move FcMetricsMonitor initialization into Microvm
This way, the lifecycle of the monitor perfectly matches that of the firecracker process (as it is started up when the Firecracker process starts, and gets terminated when the microvm is killed). This also means that the assertion the previous commit introduces will only trigger during teardown (or when explicitly killing microVMs), at which will be _after_ all other test-specific metrics have been emitted (which means that triggering the assertion will not lead to loosing performance metrics). Also just start the monitor thread in the constructor, since all call-sites just immediately started it anyway. Signed-off-by: Patrick Roy <[email protected]>
1 parent 27f0b3d commit be2f41a

File tree

7 files changed

+15
-39
lines changed

7 files changed

+15
-39
lines changed

tests/framework/microvm.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from framework.microvm_helpers import MicrovmHelpers
4040
from framework.properties import global_props
4141
from framework.utils_drive import VhostUserBlkBackend, VhostUserBlkBackendType
42+
from host_tools.fcmetrics import FCMetricsMonitor
4243
from host_tools.memory import MemoryMonitor
4344

4445
LOG = logging.getLogger("microvm")
@@ -558,6 +559,7 @@ def spawn(
558559
log_show_level=False,
559560
log_show_origin=False,
560561
metrics_path="fc.ndjson",
562+
emit_metrics: bool = False,
561563
):
562564
"""Start a microVM as a daemon or in a screen session."""
563565
# pylint: disable=subprocess-run-check
@@ -583,6 +585,8 @@ def spawn(
583585
self.metrics_file.touch()
584586
self.create_jailed_resource(self.metrics_file)
585587
self.jailer.extra_args.update({"metrics-path": self.metrics_file.name})
588+
else:
589+
assert not emit_metrics
586590

587591
if self.metadata_file:
588592
if os.path.exists(self.metadata_file):
@@ -619,6 +623,9 @@ def spawn(
619623

620624
self._spawned = True
621625

626+
if emit_metrics:
627+
self.monitors.append(FCMetricsMonitor(self))
628+
622629
# Wait for the jailer to create resources needed, and Firecracker to
623630
# create its API socket.
624631
# We expect the jailer to start within 80 ms. However, we wait for

tests/host_tools/fcmetrics.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ def __init__(self, vm, timer=60):
500500
"guest_kernel": vm.kernel_file.stem[2:],
501501
}
502502
)
503+
self.start()
503504

504505
def _flush_metrics(self):
505506
"""

tests/integration_tests/performance/test_block_ab.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import host_tools.drive as drive_tools
1313
from framework.utils import CmdBuilder, check_output, track_cpu_utilization
14-
from host_tools.fcmetrics import FCMetricsMonitor
1514

1615
# size of the block device used in the test, in MB
1716
BLOCK_DEVICE_SIZE_MB = 2048
@@ -155,7 +154,7 @@ def test_block_performance(
155154
Execute block device emulation benchmarking scenarios.
156155
"""
157156
vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
158-
vm.spawn(log_level="Info")
157+
vm.spawn(log_level="Info", emit_metrics=True)
159158
vm.basic_config(vcpu_count=vcpus, mem_size_mib=GUEST_MEM_MIB)
160159
vm.add_net_iface()
161160
# Add a secondary block device for benchmark tests.
@@ -174,8 +173,6 @@ def test_block_performance(
174173
**vm.dimensions,
175174
}
176175
)
177-
fcmetrics = FCMetricsMonitor(vm)
178-
fcmetrics.start()
179176

180177
vm.pin_threads(0)
181178

@@ -187,8 +184,6 @@ def test_block_performance(
187184
for value in values:
188185
metrics.put_metric(f"cpu_utilization_{thread_name}", value, "Percent")
189186

190-
fcmetrics.stop()
191-
192187

193188
@pytest.mark.nonci
194189
@pytest.mark.parametrize("vcpus", [1, 2], ids=["1vcpu", "2vcpu"])
@@ -208,7 +203,7 @@ def test_block_vhost_user_performance(
208203
"""
209204

210205
vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
211-
vm.spawn(log_level="Info")
206+
vm.spawn(log_level="Info", emit_metrics=True)
212207
vm.basic_config(vcpu_count=vcpus, mem_size_mib=GUEST_MEM_MIB)
213208
vm.add_net_iface()
214209

@@ -226,8 +221,6 @@ def test_block_vhost_user_performance(
226221
**vm.dimensions,
227222
}
228223
)
229-
fcmetrics = FCMetricsMonitor(vm)
230-
fcmetrics.start()
231224

232225
next_cpu = vm.pin_threads(0)
233226
vm.disks_vhost_user["scratch"].pin(next_cpu)
@@ -239,5 +232,3 @@ def test_block_vhost_user_performance(
239232
for thread_name, values in cpu_util.items():
240233
for value in values:
241234
metrics.put_metric(f"cpu_utilization_{thread_name}", value, "Percent")
242-
243-
fcmetrics.stop()

tests/integration_tests/performance/test_memory_overhead.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import psutil
2121
import pytest
2222

23-
from host_tools.fcmetrics import FCMetricsMonitor
24-
2523
# If guest memory is >3328MB, it is split in a 2nd region
2624
X86_MEMORY_GAP_START = 3328 * 2**20
2725

@@ -40,15 +38,13 @@ def test_memory_overhead(
4038

4139
for _ in range(5):
4240
microvm = microvm_factory.build(guest_kernel, rootfs)
43-
microvm.spawn()
41+
microvm.spawn(emit_metrics=True)
4442
microvm.basic_config(vcpu_count=vcpu_count, mem_size_mib=mem_size_mib)
4543
microvm.add_net_iface()
4644
microvm.start()
4745
metrics.set_dimensions(
4846
{"performance_test": "test_memory_overhead", **microvm.dimensions}
4947
)
50-
fcmetrics = FCMetricsMonitor(microvm)
51-
fcmetrics.start()
5248
microvm.wait_for_up()
5349

5450
guest_mem_bytes = mem_size_mib * 2**20
@@ -84,4 +80,3 @@ def test_memory_overhead(
8480
for metric in ["uss", "text"]:
8581
val = getattr(mem_info, metric)
8682
metrics.put_metric(metric, val, unit="Bytes")
87-
fcmetrics.stop()

tests/integration_tests/performance/test_network_ab.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import pytest
88

99
from framework.utils_iperf import IPerf3Test, emit_iperf3_metrics
10-
from host_tools.fcmetrics import FCMetricsMonitor
1110

1211

1312
def consume_ping_output(ping_putput, request_per_round):
@@ -45,7 +44,7 @@ def network_microvm(request, microvm_factory, guest_kernel, rootfs):
4544
guest_vcpus = request.param
4645

4746
vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
48-
vm.spawn(log_level="Info")
47+
vm.spawn(log_level="Info", emit_metrics=True)
4948
vm.basic_config(vcpu_count=guest_vcpus, mem_size_mib=guest_mem_mib)
5049
vm.add_net_iface()
5150
vm.start()
@@ -71,8 +70,6 @@ def test_network_latency(network_microvm, metrics):
7170
**network_microvm.dimensions,
7271
}
7372
)
74-
fcmetrics = FCMetricsMonitor(network_microvm)
75-
fcmetrics.start()
7673

7774
samples = []
7875
host_ip = network_microvm.iface["eth0"]["iface"].host_ip
@@ -83,7 +80,6 @@ def test_network_latency(network_microvm, metrics):
8380
)
8481

8582
samples.extend(consume_ping_output(ping_output, request_per_round))
86-
fcmetrics.stop()
8783

8884
for sample in samples:
8985
metrics.put_metric("ping_latency", sample, "Milliseconds")
@@ -124,8 +120,6 @@ def test_network_tcp_throughput(
124120
**network_microvm.dimensions,
125121
}
126122
)
127-
fcmetrics = FCMetricsMonitor(network_microvm)
128-
fcmetrics.start()
129123

130124
test = IPerf3Test(
131125
microvm=network_microvm,
@@ -140,4 +134,3 @@ def test_network_tcp_throughput(
140134
data = test.run_test(network_microvm.vcpus_count + 2)
141135

142136
emit_iperf3_metrics(metrics, data, warmup_sec)
143-
fcmetrics.stop()

tests/integration_tests/performance/test_snapshot_ab.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
import host_tools.drive as drive_tools
1212
from framework.microvm import Microvm
13-
from host_tools.fcmetrics import FCMetricsMonitor
1413

1514
USEC_IN_MSEC = 1000
1615
ITERATIONS = 30
@@ -53,7 +52,7 @@ def configure_vm(
5352
rootfs,
5453
monitor_memory=False,
5554
)
56-
vm.spawn(log_level="Info")
55+
vm.spawn(log_level="Info", emit_metrics=True)
5756
vm.time_api_requests = False
5857
vm.basic_config(
5958
vcpu_count=self.vcpus,
@@ -88,11 +87,9 @@ def sample_latency(
8887
kernel=guest_kernel_linux_4_14,
8988
monitor_memory=False,
9089
)
91-
microvm.spawn()
90+
microvm.spawn(emit_metrics=True)
9291
snapshot_copy = microvm.restore_from_snapshot(snapshot, resume=True)
9392

94-
fcmetrics = FCMetricsMonitor(microvm)
95-
fcmetrics.start()
9693
microvm.wait_for_up()
9794

9895
value = 0
@@ -106,7 +103,6 @@ def sample_latency(
106103
break
107104
assert value > 0
108105
values.append(value)
109-
fcmetrics.stop()
110106
microvm.kill()
111107
snapshot_copy.delete()
112108

@@ -154,11 +150,8 @@ def test_restore_latency(
154150
**vm.dimensions,
155151
}
156152
)
157-
fcmetrics = FCMetricsMonitor(vm)
158-
fcmetrics.start()
159153

160154
snapshot = vm.snapshot_full()
161-
fcmetrics.stop()
162155
vm.kill()
163156

164157
samples = test_setup.sample_latency(

tests/integration_tests/performance/test_vsock_ab.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
from framework.utils_iperf import IPerf3Test, emit_iperf3_metrics
1010
from framework.utils_vsock import VSOCK_UDS_PATH, make_host_port_path
11-
from host_tools.fcmetrics import FCMetricsMonitor
1211

1312

1413
class VsockIPerf3Test(IPerf3Test):
@@ -87,7 +86,7 @@ def test_vsock_throughput(
8786

8887
mem_size_mib = 1024
8988
vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
90-
vm.spawn(log_level="Info")
89+
vm.spawn(log_level="Info", emit_metrics=True)
9190
vm.basic_config(vcpu_count=vcpus, mem_size_mib=mem_size_mib)
9291
vm.add_net_iface()
9392
# Create a vsock device
@@ -102,13 +101,10 @@ def test_vsock_throughput(
102101
**vm.dimensions,
103102
}
104103
)
105-
fcmetrics = FCMetricsMonitor(vm)
106-
fcmetrics.start()
107104

108105
vm.pin_threads(0)
109106

110107
test = VsockIPerf3Test(vm, mode, payload_length)
111108
data = test.run_test(vm.vcpus_count + 2)
112109

113-
fcmetrics.stop()
114110
emit_iperf3_metrics(metrics, data, VsockIPerf3Test.WARMUP_SEC)

0 commit comments

Comments
 (0)