Skip to content

Commit 45842cb

Browse files
committed
test: stop CPU load monitoring at the end of a test
We see errors during teardown. It is then not clear if the CPU usage happened during the call phase of the test (which would be legit) or the teardown (which would be a false positive). Restrict the CPU load monitoring part to only the part of the test we are interested in. Also remove the CPU load monitoring from Microvm, since this is the only user and it fits better as a Context Manager. Signed-off-by: Pablo Barbáchano <[email protected]>
1 parent dd5aaba commit 45842cb

File tree

3 files changed

+32
-36
lines changed

3 files changed

+32
-36
lines changed

tests/framework/microvm.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
from retry import retry
2828

2929
import host_tools.cargo_build as build_tools
30-
import host_tools.cpu_load as cpu_tools
3130
import host_tools.logging as log_tools
3231
import host_tools.memory as mem_tools
3332
import host_tools.network as net_tools
@@ -167,9 +166,6 @@ def __init__(
167166
if monitor_memory:
168167
self.memory_monitor = mem_tools.MemoryMonitor()
169168

170-
# Cpu load monitoring has to be explicitly enabled using
171-
# the `enable_cpu_load_monitor` method.
172-
self._cpu_load_monitor = None
173169
self.vcpus_count = None
174170

175171
# External clone/exec tool, because Python can't into clone
@@ -221,11 +217,6 @@ def kill(self):
221217
self.memory_monitor.join(timeout=1)
222218
self.memory_monitor.check_samples()
223219

224-
if self._cpu_load_monitor:
225-
self._cpu_load_monitor.signal_stop()
226-
self._cpu_load_monitor.join()
227-
self._cpu_load_monitor.check_samples()
228-
229220
@property
230221
def firecracker_version(self):
231222
"""Return the version of the Firecracker executable."""
@@ -333,18 +324,6 @@ def append_to_log_data(self, data):
333324
with data_lock:
334325
self.__log_data += data
335326

336-
def enable_cpu_load_monitor(self, threshold):
337-
"""Enable the cpu load monitor."""
338-
process_pid = self.jailer_clone_pid
339-
# We want to monitor the emulation thread, which is currently
340-
# the first one created.
341-
# A possible improvement is to find it by name.
342-
thread_pid = self.jailer_clone_pid
343-
self._cpu_load_monitor = cpu_tools.CpuLoadMonitor(
344-
process_pid, thread_pid, threshold
345-
)
346-
self._cpu_load_monitor.start()
347-
348327
def copy_to_jail_ramfs(self, src):
349328
"""Copy a file to a jail ramfs."""
350329
filename = os.path.basename(src)

tests/host_tools/cpu_load.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66

77
from framework import utils
88

9-
# /proc/<pid>/stat output taken from
10-
# https://www.man7.org/linux/man-pages/man5/proc.5.html
11-
STAT_UTIME_IDX = 13
12-
STAT_STIME_IDX = 14
13-
STAT_STARTTIME_IDX = 21
14-
159

1610
class CpuLoadExceededException(Exception):
1711
"""A custom exception containing details on excessive cpu load."""
@@ -88,3 +82,18 @@ def check_samples(self):
8882
"""Check that there are no samples above the threshold."""
8983
if len(self.cpu_load_samples) > 0:
9084
raise CpuLoadExceededException(self._cpu_load_samples, self._threshold)
85+
86+
def __enter__(self):
87+
"""Functions to use this CPU Load class as a Context Manager
88+
89+
>>> clm = CpuLoadMonitor(1000, 1000, 45)
90+
>>> with clm:
91+
>>> # do stuff
92+
"""
93+
self.start()
94+
95+
def __exit__(self, _type, _value, _traceback):
96+
"""Exit context"""
97+
self.check_samples()
98+
self.signal_stop()
99+
self.join()

tests/integration_tests/functional/test_rate_limiter.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import time
55

66
from framework import utils
7+
from host_tools import cpu_load
78

89
# The iperf version to run this tests with
910
IPERF_BINARY = "iperf3"
@@ -146,16 +147,8 @@ def test_rx_rate_limiting_cpu_load(test_microvm_with_api, network_config):
146147
"""
147148
test_microvm = test_microvm_with_api
148149
test_microvm.spawn()
149-
150150
test_microvm.basic_config()
151151

152-
# Enable monitor that checks if the cpu load is over the threshold.
153-
# After multiple runs, the average value for the cpu load
154-
# seems to be around 10%. Setting the threshold a little
155-
# higher to skip false positives.
156-
threshold = 20
157-
test_microvm.enable_cpu_load_monitor(threshold)
158-
159152
# Create interface with aggressive rate limiting enabled.
160153
rx_rate_limiter_no_burst = {
161154
"bandwidth": {"size": 65536, "refill_time": 1000} # 64KBytes # 1s
@@ -165,6 +158,7 @@ def test_rx_rate_limiting_cpu_load(test_microvm_with_api, network_config):
165158
)
166159

167160
test_microvm.start()
161+
168162
# Start iperf server on guest.
169163
_start_iperf_on_guest(test_microvm, guest_ip)
170164

@@ -175,7 +169,21 @@ def test_rx_rate_limiting_cpu_load(test_microvm_with_api, network_config):
175169
guest_ip,
176170
IPERF_TRANSMIT_TIME * 5,
177171
)
178-
_iperf_out = _run_local_iperf(iperf_cmd)
172+
173+
# Enable monitor that checks if the cpu load is over the threshold.
174+
# After multiple runs, the average value for the cpu load
175+
# seems to be around 10%. Setting the threshold a little
176+
# higher to skip false positives.
177+
# We want to monitor the emulation thread, which is currently
178+
# the first one created.
179+
# A possible improvement is to find it by name.
180+
cpu_load_monitor = cpu_load.CpuLoadMonitor(
181+
process_pid=test_microvm.jailer_clone_pid,
182+
thread_pid=test_microvm.jailer_clone_pid,
183+
threshold=20,
184+
)
185+
with cpu_load_monitor:
186+
_run_local_iperf(iperf_cmd)
179187

180188

181189
def _check_tx_rate_limiting(test_microvm, guest_ips, host_ips):

0 commit comments

Comments
 (0)