Skip to content

Commit 24c268d

Browse files
author
Kurt Biery
committed
Merge remote-tracking branch 'origin/develop' into kbiery/asset_file_refresh
2 parents cd5922b + 3045b28 commit 24c268d

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 desired
22+
# resval_debug_string = resval.get_debug_string()
23+
# print(f"{resval_debug_string}")
24+
# # then, in 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+
39+
hostname = os.uname().nodename
40+
self.report_header = f"This computer ({hostname}) does not have enough resources to run this test."
41+
self.report_indentation = " *"
42+
43+
self.debug_string = ""
44+
self.report_string = ""
45+
46+
self.free_disk_space_gb = -1
47+
48+
def require_cpu_count(self, minimum_cpu_count):
49+
cpu_count = os.cpu_count()
50+
self.debug_string += f"\nDEBUG: CPU count is {cpu_count}, minimum required number is {minimum_cpu_count}."
51+
if cpu_count < minimum_cpu_count:
52+
self.this_computer_has_sufficient_resources = False
53+
if len(self.report_string) == 0:
54+
self.report_string = self.report_header
55+
self.report_string += f"\n{self.report_indentation} CPU count is {cpu_count}, minimum CPU count is {minimum_cpu_count}."
56+
57+
def require_free_memory_gb(self, minimum_free_memory):
58+
mem_obj = psutil.virtual_memory()
59+
free_mem = round((mem_obj.available / (1024 * 1024 * 1024)), 2)
60+
self.debug_string += f"\nDEBUG: Free memory is {free_mem} GB, minimum required amount is {minimum_free_memory}."
61+
if free_mem < minimum_free_memory:
62+
self.this_computer_has_sufficient_resources = False
63+
if len(self.report_string) == 0:
64+
self.report_string = self.report_header
65+
self.report_string += f"\n{self.report_indentation} Free memory is {free_mem} GB, minimum amount is {minimum_free_memory}."
66+
67+
def require_total_memory_gb(self, minimum_total_memory):
68+
mem_obj = psutil.virtual_memory()
69+
total_mem = round((mem_obj.total / (1024 * 1024 * 1024)), 2)
70+
self.debug_string += f"\nDEBUG: Total memory is {total_mem} GB, minimum required amount is {minimum_total_memory}."
71+
if total_mem < minimum_total_memory:
72+
self.this_computer_has_sufficient_resources = False
73+
if len(self.report_string) == 0:
74+
self.report_string = self.report_header
75+
self.report_string += f"\n{self.report_indentation} Total memory is {total_mem} GB, minimum amount is {minimum_total_memory}."
76+
77+
def require_free_disk_space_gb(self, path_of_interest, minimum_free_disk_space):
78+
disk_space = shutil.disk_usage(path_of_interest)
79+
self.free_disk_space_gb = disk_space.free / (1024 * 1024 * 1024)
80+
self.debug_string += f"\nDEBUG: Free disk space on \"{path_of_interest}\" is {self.free_disk_space_gb} GB, minimum required amount is {minimum_free_disk_space}."
81+
if self.free_disk_space_gb < minimum_free_disk_space:
82+
self.this_computer_has_sufficient_resources = False
83+
if len(self.report_string) == 0:
84+
self.report_string = self.report_header
85+
self.report_string += f"\n{self.report_indentation} Free disk space on \"{path_of_interest}\" is {self.free_disk_space_gb} GB, minimum amount is {minimum_free_disk_space}."
86+
87+
def require_total_disk_space_gb(self, path_of_interest, minimum_total_disk_space):
88+
disk_space = shutil.disk_usage(path_of_interest)
89+
total_disk_space = disk_space.total / (1024 * 1024 * 1024)
90+
self.debug_string += f"\nDEBUG: Total disk space on \"{path_of_interest}\" is {total_disk_space} GB, minimum required amount is {minimum_total_disk_space}."
91+
if total_disk_space < minimum_total_disk_space:
92+
self.this_computer_has_sufficient_resources = False
93+
if len(self.report_string) == 0:
94+
self.report_string = self.report_header
95+
self.report_string += f"\n{self.report_indentation} Total disk space on \"{path_of_interest}\" is {total_disk_space} GB, minimum amount is {minimum_total_disk_space}."
96+
97+
def get_debug_string(self):
98+
return self.debug_string
99+
100+
def get_insufficient_resources_report(self):
101+
return self.report_string
102+
103+
def get_insufficient_resources_summary(self):
104+
return self.report_header

0 commit comments

Comments
 (0)