Skip to content

Commit 423efb3

Browse files
authored
🔨 disk-usage pytest plugin (#6196)
1 parent 6773ddc commit 423efb3

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import logging
2+
import shutil
3+
4+
import pytest
5+
6+
_logger = logging.getLogger(__name__)
7+
_DEFAULT_THREADHOLD_MB = 512
8+
9+
10+
def pytest_addoption(parser):
11+
simcore_group = parser.getgroup("simcore")
12+
simcore_group.addoption(
13+
"--disk-usage", action="store_true", help="Enable disk usage monitoring"
14+
)
15+
simcore_group.addoption(
16+
"--disk-usage-threshold",
17+
action="store",
18+
type=float,
19+
default=_DEFAULT_THREADHOLD_MB,
20+
help="Set the threshold for disk usage increase in Megabytes. No warning if increase is below this value. [default={_DEFAULT_THREADHOLD_MB}]",
21+
)
22+
23+
24+
@pytest.hookimpl(tryfirst=True)
25+
def pytest_configure(config):
26+
"""Check if the disk usage monitoring is enabled and register the plugin."""
27+
if config.getoption("--disk-usage"):
28+
config.pluginmanager.register(DiskUsagePlugin(config), "disk_usage_plugin")
29+
30+
31+
class DiskUsagePlugin:
32+
"""
33+
The purpose of this plugin is to monitor disk usage during test execution, identifying tests
34+
that do not properly clean up resources. This helps prevent potential issues when running
35+
continuous integration (CI) pipelines on external systems, such as GitHub Actions.
36+
37+
The plugin is activated by using the `--disk-usage` option, and
38+
it can be configured with a custom threshold using the `--disk-usage-threshold` option.
39+
40+
Warnings are generated if disk usage increases beyond the specified threshold,
41+
allowing for targeted investigation of resource management
42+
in specific tests, modules, or the entire test session.
43+
44+
As example, the CI in gh-actions reported this:
45+
XMinioStorageFull: Storage backend has reached its minimum free drive threshold. Please delete a few objects to proceed.
46+
"""
47+
48+
def __init__(self, config):
49+
self._threshold_mb = config.getoption("--disk-usage-threshold")
50+
51+
@staticmethod
52+
def _get_disk_usage():
53+
return shutil.disk_usage("/").used
54+
55+
def _log_disk_usage_increase(
56+
self, initial_usage: int, final_usage: int, scope_name: str
57+
):
58+
if final_usage > initial_usage:
59+
increase = final_usage - initial_usage
60+
61+
if increase >= self._threshold_mb:
62+
increase_mb = increase / (1024 * 1024)
63+
msg = (
64+
f"Disk usage increased by {increase_mb:.2f} MB during {scope_name}."
65+
)
66+
_logger.warning(msg)
67+
68+
@pytest.fixture(scope="session", autouse=True)
69+
def monitor_session_disk_usage(self):
70+
"""SESSION-level fixture to monitor overall disk usage."""
71+
initial_usage = self._get_disk_usage()
72+
73+
yield
74+
75+
final_usage = self._get_disk_usage()
76+
self._log_disk_usage_increase(initial_usage, final_usage, "this session")
77+
78+
@pytest.fixture(scope="module", autouse=True)
79+
def monitor_module_disk_usage(self, request):
80+
"""MODULE-level fixture to monitor disk usage before and after each module."""
81+
initial_usage = self._get_disk_usage()
82+
83+
yield
84+
85+
final_usage = self._get_disk_usage()
86+
module_name = request.module.__name__
87+
self._log_disk_usage_increase(
88+
initial_usage, final_usage, f"the module '{module_name}'"
89+
)
90+
91+
@pytest.fixture(autouse=True)
92+
def monitor_test_disk_usage(self, request):
93+
"""FUNCTION-level fixture to monitor disk usage before and after each test."""
94+
initial_usage = self._get_disk_usage()
95+
96+
yield
97+
98+
final_usage = self._get_disk_usage()
99+
test_name = request.node.name
100+
self._log_disk_usage_increase(
101+
initial_usage, final_usage, f"the test '{test_name}'"
102+
)

packages/simcore-sdk/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,16 @@ tests-integration-ci: ## runs integration tests against local+production images
7575
--asyncio-mode=auto \
7676
--color=yes \
7777
--cov-append \
78+
--disk-usage \
79+
--disk-usage-threshold=20 \
7880
--cov-config=../../.coveragerc \
7981
--cov-report=term-missing \
8082
--cov-report=xml \
8183
--cov=simcore_sdk \
8284
--durations=10 \
8385
--keep-docker-up \
8486
--log-date-format="%Y-%m-%d %H:%M:%S" \
87+
--log-cli-level=WARNING \
8588
--verbose \
8689
-m "not heavy_load" \
8790
--log-format="%(asctime)s %(levelname)s %(message)s" \

packages/simcore-sdk/tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
pytest_plugins = [
2222
"pytest_simcore.aws_s3_service",
2323
"pytest_simcore.aws_server",
24+
"pytest_simcore.disk_usage_monitoring",
2425
"pytest_simcore.docker_compose",
2526
"pytest_simcore.docker_swarm",
2627
"pytest_simcore.file_extra",

0 commit comments

Comments
 (0)