Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 39 additions & 33 deletions src/tests/ftest/util/pool_create_all_base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
(C) Copyright 2022-2024 Intel Corporation.
(C) Copyright 2025 Hewlett Packard Enterprise Development LP
(C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP

SPDX-License-Identifier: BSD-2-Clause-Patent
"""
Expand Down Expand Up @@ -111,10 +111,11 @@ def check_pool_full_storage(self, scm_delta_bytes, nvme_delta_bytes=None, ranks=
pool_idx = len(self.pool) - pool_count

# pylint: disable-next=logging-format-truncated
self.log.info("Creating a pool with all the available storage: size=100%")
self.pool[pool_idx].size.update("100%", "pool[{}].size".format(pool_idx))
self.log_step(
f"Creating a TestPool_{pool_idx + 1} with all the available storage: size=100%")
self.pool[pool_idx].size.update("100%", f"pool[{pool_idx}].size")
if ranks is not None:
self.pool[pool_idx].target_list.update(ranks, "pool[{}].target_list".format(pool_idx))
self.pool[pool_idx].target_list.update(ranks, f"pool[{pool_idx}].target_list")
self.pool[pool_idx].create()
self.pool[pool_idx].get_info()
tier_bytes = self.pool[pool_idx].info.pi_space.ps_space.s_total
Expand All @@ -125,8 +126,11 @@ def check_pool_full_storage(self, scm_delta_bytes, nvme_delta_bytes=None, ranks=
self.assertListEqual(
wait_ranks,
got_ranks,
"Pool with invalid ranks: wait={} got={}".format(wait_ranks, got_ranks))
f"Pool with invalid ranks: wait={wait_ranks} got={got_ranks}")
self.log.info("Pool created: scm_size=%d, nvme_size=%d", *tier_bytes)
self.log_step(f"Verifying TestPool_{pool_idx + 1} default attributes")
self.pool[pool_idx].verify_props()
self.log_step(f"Destroying TestPool_{pool_idx + 1}")
self.pool[pool_idx].destroy()
pool_idx += 1

Expand All @@ -138,32 +142,33 @@ def check_pool_full_storage(self, scm_delta_bytes, nvme_delta_bytes=None, ranks=
nvme_delta_bytes is None,
"Invalid function call: no NVME delta with usable NVMe storage")

self.log.info(
"Creating a pool with all the available storage: scm_size=%d, nvme_size=%d",
dmg_scm_size,
dmg_nvme_size)
self.pool[pool_idx].scm_size.update(dmg_scm_size, "pool[{}].scm_size", pool_idx)
self.log_step(
f"Creating a pool with all the available storage: scm_size={dmg_scm_size}, "
f"nvme_size={dmg_nvme_size}")
self.pool[pool_idx].scm_size.update(dmg_scm_size, f"pool[{pool_idx}].scm_size")
if dmg_nvme_size > 0:
self.pool[pool_idx].nvme_size.update(dmg_nvme_size, "pool[{}].nvme_size", pool_idx)
self.pool[pool_idx].nvme_size.update(dmg_nvme_size, f"pool[{pool_idx}].nvme_size")
if ranks is not None:
self.pool[pool_idx].target_list.update(ranks, "pool[{}].target_list".format(pool_idx))
self.pool[pool_idx].target_list.update(ranks, f"pool[{pool_idx}].target_list")
self.pool[pool_idx].create()
self.log_step(f"Verifying TestPool_{pool_idx + 1} default attributes")
self.pool[pool_idx].verify_props()
self.log_step(f"Destroying TestPool_{pool_idx + 1}")
self.pool[pool_idx].destroy()
pool_idx += 1

self.log.info(
"Creating a pool with SCM oversubscription: scm_size=%d nvme_size=%d",
dmg_scm_size + scm_delta_bytes,
dmg_nvme_size)
self.log_step(
f"Creating a pool with SCM oversubscription: scm_size={dmg_scm_size}, "
f"nvme_size={dmg_nvme_size}")
self.pool[pool_idx].scm_size.update(
dmg_scm_size + scm_delta_bytes,
"pool[{}].scm_size".format(pool_idx))
f"pool[{pool_idx}].scm_size")
if dmg_nvme_size > 0:
self.pool[pool_idx].nvme_size.update(
dmg_nvme_size,
"pool[{}].nvme_size".format(pool_idx))
f"pool[{pool_idx}].nvme_size")
if ranks is not None:
self.pool[pool_idx].target_list.update(ranks, "pool[{}].target_list".format(pool_idx))
self.pool[pool_idx].target_list.update(ranks, f"pool[{pool_idx}].target_list")
error_msg = r"Pool should not be created: SCM oversubscription"
with self.assertRaises(TestFail, msg=error_msg) as context_manager:
self.pool[pool_idx].create()
Expand All @@ -174,18 +179,17 @@ def check_pool_full_storage(self, scm_delta_bytes, nvme_delta_bytes=None, ranks=
pool_idx += 1

if dmg_nvme_size > 0:
self.log.info(
"Creating a pool with NVME oversubscription: scm_size=%d, nvme_size=%d",
dmg_scm_size,
dmg_nvme_size + nvme_delta_bytes)
self.pool[pool_idx].scm_size.update(dmg_scm_size, "pool[{}].scm_size".format(pool_idx))
self.log_step(
f"Creating a pool with NVME oversubscription: scm_size={dmg_scm_size}, "
f"nvme_size={dmg_nvme_size + nvme_delta_bytes}")
self.pool[pool_idx].scm_size.update(dmg_scm_size, f"pool[{pool_idx}].scm_size")
self.pool[pool_idx].nvme_size.update(
dmg_nvme_size + nvme_delta_bytes,
"pool[{}].nvme_size".format(pool_idx))
f"pool[{pool_idx}].nvme_size")
if ranks is not None:
self.pool[pool_idx].target_list.update(
ranks,
"pool[{}].target_list".format(pool_idx))
f"pool[{pool_idx}].target_list")
error_msg = r"Pool should not be created: NVME oversubscription"
with self.assertRaises(TestFail, msg=error_msg) as context_manager:
self.pool[pool_idx].create()
Expand All @@ -195,18 +199,20 @@ def check_pool_full_storage(self, scm_delta_bytes, nvme_delta_bytes=None, ranks=
"Pool creation failed with invalid error message")
pool_idx += 1

self.log.info(
"Creating a pool with 100%% of the available storage: scm_size=%d, nvme_size=%d",
dmg_scm_size,
dmg_nvme_size)
self.pool[pool_idx].scm_size.update(dmg_scm_size, "pool[{}].scm_size".format(pool_idx))
self.log_step(
f"Creating a pool with 100%% of the available storage: scm_size={dmg_scm_size}, "
f"nvme_size={dmg_nvme_size}")
self.pool[pool_idx].scm_size.update(dmg_scm_size, f"pool[{pool_idx}].scm_size")
if dmg_nvme_size > 0:
self.pool[pool_idx].nvme_size.update(
dmg_nvme_size,
"pool[{}].nvme_size".format(pool_idx))
f"pool[{pool_idx}].nvme_size")
if ranks is not None:
self.pool[pool_idx].target_list.update(ranks, "pool[{}].target_list".format(pool_idx))
self.pool[pool_idx].target_list.update(ranks, f"pool[{pool_idx}].target_list")
self.pool[pool_idx].create()
self.log_step(f"Verifying TestPool_{pool_idx + 1} default attributes")
self.pool[pool_idx].verify_props()
self.log_step(f"Destroying TestPool_{pool_idx + 1}")
self.pool[pool_idx].destroy()

def check_pool_recycling(self, pool_count, scm_delta_bytes, nvme_delta_bytes=None):
Expand Down
62 changes: 62 additions & 0 deletions src/tests/ftest/util/test_utils_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@

POOL_NAMESPACE = "/run/pool/*"
POOL_TIMEOUT_INCREMENT = 200
DEFAULT_POOL_PROPS = {
"checkpoint": "timed",
"checkpoint_freq": 50,
"data_thresh": 4096,
"ec_cell_sz": 131072, # 128 KiB
"ec_pda": 1,
"global_version": 4,
"perf_domain": "root",
"rd_fac": 3,
"reclaim": "lazy",
"reintegration": "data_sync",
"rp_pda": 4294967295,
"scrub": "off",
"scrub_freq": 604800,
"scrub_thresh": 0,
"self_heal": "exclude;rebuild",
"space_rb": 5,
"svc_ops_enabled": 1,
"svc_ops_entry_age": 300,
"svc_rf": 2,
"upgrade_status": "not started"
}


def add_pools(dmg, add_pool_kwargs, error_handler=None):
Expand Down Expand Up @@ -1648,3 +1670,43 @@
raise AssertionError(
f'Expected target {target} to be in state {expected_target_state}, '
f'but current state is {info["target_state"]}')

# pylint: disable=dangerous-default-value
def verify_props(self, expected=DEFAULT_POOL_PROPS):
"""Verify pool properties match expected values.

Args:
expected (dict): Expected key/value pairs from pool properties.
Can be a subset of the full properties, where only expected keys are verified.
Defaults to DEFAULT_POOL_PROPS.

Raises:
TestFail: If any of the default properties are missing or have invalid values.
"""
errors = {
"types": set(),
"details": []
}

try:
data = {}
for entry in self.get_prop()['response']:
data[entry['name']] = entry['value']
for key, value in expected.items():
if key not in data:
errors["types"].add("missing property")
errors["details"].append(f"Missing property: {key}")
continue
if data[key] != value:
errors["types"].add("property value")
errors["details"].append(
f"Invalid value for property: {key}, expected: {value}, got: {data[key]}")
except TestFail as error:
errors["types"].add("retrieval error")
errors["details"].append(f"Error retrieving pool properties: {str(error)}")

if errors["types"]:
self.log.error("Errors detected verifying pool properties:")
for error in errors["details"]:
self.log.error(f" - {error}")

Check warning on line 1711 in src/tests/ftest/util/test_utils_pool.py

View workflow job for this annotation

GitHub Actions / Pylint check

logging-fstring-interpolation, Use lazy % formatting in logging functions
raise TestFail(f'Pool properties check failed - {", ".join(errors["types"])}')
Loading