Skip to content

Commit 9457515

Browse files
author
Kurt Biery
committed
Added a class to help with checking the available resources on the computers where integration tests are run.
1 parent 37beccd commit 9457515

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# 01-Oct-2025, KAB: This code is intended to provide a utility class that takes care
2+
# of checking whether the current computer has sufficient resources (memory, CPU,
3+
# disk space) for running a given integrationtest.
4+
#
5+
# The intention is that users would create an instance of the ResourceValidator in their
6+
# integtest code, set whichever minimum sizes they want to enforce, and call the
7+
# appropriate methods in the ResourceValidator instance to see where sufficient resources
8+
# are available. Only the resources that have been explicitly set in the
9+
# ResourceValidator instance are considered when determining if sufficient resources are
10+
# available.
11+
#
12+
# The current implementation is not bullet-proof. A given resource limit value should only
13+
# be set once.
14+
#
15+
# Here is pseudo-code for using this utility:
16+
#
17+
# import integrationtest.resource_validation as resource_validation
18+
# resval = resource_validation.ResourceValidator()
19+
# resval.require_cpu_count(64)
20+
# resval.require_free_memory_gb(28)
21+
# # set other minimum values, if needed
22+
# resval_debug_string = resval.get_debug_string()
23+
# print(f"{resval_debug_string}")
24+
# # skip to one of the pytest "tests"
25+
# if not resval.this_computer_has_sufficient_resources:
26+
# resval_full_report = resval.get_insufficient_resources_report()
27+
# print(f"{resval_full_report}")
28+
# resval_summary_report = resval.get_insufficient_resources_summary()
29+
# pytest.skip(f"{resval_summary_report}")
30+
31+
import os
32+
import psutil
33+
import shutil
34+
35+
class ResourceValidator:
36+
def __init__(self):
37+
self.this_computer_has_sufficient_resources = True
38+
self.debug_string = ""
39+
self.report_string = ""
40+
hostname = os.uname().nodename
41+
self.report_header = f"This computer ({hostname}) does not have enough resources to run this test."
42+
43+
def get_report_header(self):
44+
return self.report_header
45+
46+
def get_report_indentation(self):
47+
return " *"
48+
49+
def require_cpu_count(self, minimum_cpu_count):
50+
cpu_count = os.cpu_count()
51+
self.debug_string += f"\nDEBUG: CPU count is {cpu_count}, minimum required number is {minimum_cpu_count}."
52+
if cpu_count < minimum_cpu_count:
53+
self.this_computer_has_sufficient_resources = False
54+
if len(self.report_string) == 0:
55+
self.report_string = self.get_report_header()
56+
self.report_string += f"\n{self.get_report_indentation()} CPU count is {cpu_count}, Minimum CPU count is {minimum_cpu_count}."
57+
58+
def require_free_memory_gb(self, minimum_free_memory):
59+
mem_obj = psutil.virtual_memory()
60+
free_mem = round((mem_obj.available / (1024 * 1024 * 1024)), 2)
61+
self.debug_string += f"\nDEBUG: Free memory is {free_mem} GB, minimum required amount is {minimum_free_memory}."
62+
if free_mem < minimum_free_memory:
63+
self.this_computer_has_sufficient_resources = False
64+
if len(self.report_string) == 0:
65+
self.report_string = self.get_report_header()
66+
self.report_string += f"\n{self.get_report_indentation()} Free memory is {free_mem} GB, minimum amount is {minimum_free_memory}."
67+
68+
def require_total_memory_gb(self, minimum_total_memory):
69+
mem_obj = psutil.virtual_memory()
70+
total_mem = round((mem_obj.total / (1024 * 1024 * 1024)), 2)
71+
self.debug_string += f"\nDEBUG: Total memory is {total_mem} GB, minimum required amount is {minimum_total_memory}."
72+
if total_mem < minimum_total_memory:
73+
self.this_computer_has_sufficient_resources = False
74+
if len(self.report_string) == 0:
75+
self.report_string = self.get_report_header()
76+
self.report_string += f"\n{self.get_report_indentation()} Total memory is {total_mem} GB, minimum amount is {minimum_total_memory}."
77+
78+
def require_free_disk_space_gb(self, path_of_interest, minimum_free_disk_space):
79+
disk_space = shutil.disk_usage(path_of_interest)
80+
free_disk_space = disk_space.free / (1024 * 1024 * 1024)
81+
self.debug_string += f"\nDEBUG: Free disk space is {free_disk_space} GB, minimum required amount is {minimum_free_disk_space}."
82+
if free_disk_space < minimum_free_disk_space:
83+
self.this_computer_has_sufficient_resources = False
84+
if len(self.report_string) == 0:
85+
self.report_string = self.get_report_header()
86+
self.report_string += f"\n{self.get_report_indentation()} Free disk space is {free_disk_space} GB, minimum amount is {minimum_free_disk_space}."
87+
88+
def require_total_disk_space_gb(self, path_of_interest, minimum_total_disk_space):
89+
disk_space = shutil.disk_usage(path_of_interest)
90+
total_disk_space = disk_space.total / (1024 * 1024 * 1024)
91+
self.debug_string += f"\nDEBUG: Total disk space is {total_disk_space} GB, minimum required amount is {minimum_total_disk_space}."
92+
if total_disk_space < minimum_total_disk_space:
93+
self.this_computer_has_sufficient_resources = False
94+
if len(self.report_string) == 0:
95+
self.report_string = self.get_report_header()
96+
self.report_string += f"\n{self.get_report_indentation()} Total disk space is {total_disk_space} GB, minimum amount is {minimum_total_disk_space}."
97+
98+
def get_debug_string(self):
99+
return self.debug_string
100+
101+
def get_insufficient_resources_report(self):
102+
return self.report_string
103+
104+
def get_insufficient_resources_summary(self):
105+
return self.get_report_header()

0 commit comments

Comments
 (0)