test-api: add a check for each stat parsing

Signed-off-by: Kamil Gierszewski <kamil.gierszewski@huawei.com>
This commit is contained in:
Kamil Gierszewski 2025-01-02 02:54:19 +01:00
parent 7b52a2fc00
commit bf7c72ccba
No known key found for this signature in database

View File

@ -11,6 +11,7 @@ from enum import Enum
from typing import List
from api.cas import casadm
from api.cas.casadm_params import StatsFilter
from connection.utils.output import CmdException
from type_def.size import Size, Unit
@ -58,6 +59,9 @@ class CacheStats:
case StatsFilter.err:
self.error_stats = ErrorStats(stats_dict, percentage_val)
if stats_dict:
raise CmdException(f"Unknown stat(s) left after parsing output cmd\n{stats_dict}")
def __str__(self):
# stats_list contains all Class.__str__ methods initialized in CacheStats
stats_list = [str(getattr(self, stats_item)) for stats_item in self.__dict__]
@ -72,13 +76,6 @@ class CacheStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.usage_stats -= other.usage_stats
self.request_stats -= other.request_stats
self.block_stats -= other.block_stats
self.error_stats -= other.error_stats
return self
class CoreStats:
def __init__(
@ -103,12 +100,8 @@ class CoreStats:
case StatsFilter.err:
self.error_stats = ErrorStats(stats_dict, percentage_val)
def __sub__(self, other):
self.usage_stats -= other.usage_stats
self.request_stats -= other.request_stats
self.block_stats -= other.block_stats
self.error_stats -= other.error_stats
return self
if stats_dict:
raise CmdException(f"Unknown stat(s) left after parsing output cmd\n{stats_dict}")
def __str__(self):
# stats_list contains all Class.__str__ methods initialized in CacheStats
@ -149,6 +142,9 @@ class CoreIoClassStats:
case StatsFilter.blk:
self.block_stats = BlockStats(stats_dict, percentage_val)
if stats_dict:
raise CmdException(f"Unknown stat(s) left after parsing output cmd\n{stats_dict}")
def __eq__(self, other):
# check if all initialized variable in self(CacheStats) match other(CacheStats)
return [getattr(self, stats_item) for stats_item in self.__dict__] == [
@ -163,11 +159,6 @@ class CoreIoClassStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.usage_stats -= other.usage_stats
self.request_stats -= other.request_stats
self.block_stats -= other.block_stats
class CacheIoClassStats(CoreIoClassStats):
def __init__(
@ -211,6 +202,22 @@ class CacheConfigStats:
self.dirty_for = parse_value(value=stats_dict["Dirty for [s]"], unit_type=UnitType.seconds)
self.status = stats_dict["Status"]
del stats_dict["Cache Id"]
del stats_dict["Cache Size [4KiB Blocks]"]
del stats_dict["Cache Size [GiB]"]
del stats_dict["Cache Device"]
del stats_dict["Exported Object"]
del stats_dict["Core Devices"]
del stats_dict["Inactive Core Devices"]
del stats_dict["Write Policy"]
del stats_dict["Cleaning Policy"]
del stats_dict["Promotion Policy"]
del stats_dict["Cache line size [KiB]"]
del stats_dict[footprint_key]
del stats_dict["Dirty for [s]"]
del stats_dict["Dirty for"]
del stats_dict["Status"]
def __str__(self):
return (
f"Config stats:\n"
@ -254,7 +261,7 @@ class CacheConfigStats:
class CoreConfigStats:
def __init__(self, stats_dict):
self.core_id = stats_dict["Core Id"]
self.core_id = int(stats_dict["Core Id"])
self.core_dev = stats_dict["Core Device"]
self.exp_obj = stats_dict["Exported Object"]
self.core_size = parse_value(
@ -267,6 +274,17 @@ class CoreConfigStats:
)
self.seq_cutoff_policy = stats_dict["Seq cutoff policy"]
del stats_dict["Core Id"]
del stats_dict["Core Device"]
del stats_dict["Exported Object"]
del stats_dict["Core Size [4KiB Blocks]"]
del stats_dict["Core Size [GiB]"]
del stats_dict["Dirty for [s]"]
del stats_dict["Dirty for"]
del stats_dict["Status"]
del stats_dict["Seq cutoff threshold [KiB]"]
del stats_dict["Seq cutoff policy"]
def __str__(self):
return (
f"Config stats:\n"
@ -305,6 +323,11 @@ class IoClassConfigStats:
self.eviction_priority = stats_dict["Eviction priority"]
self.max_size = stats_dict["Max size"]
del stats_dict["IO class ID"]
del stats_dict["IO class name"]
del stats_dict["Eviction priority"]
del stats_dict["Max size"]
def __str__(self):
return (
f"Config stats:\n"
@ -348,6 +371,18 @@ class UsageStats:
value=stats_dict[f"Inactive Dirty {unit}"], unit_type=unit
)
for unit in [UnitType.percentage, UnitType.block_4k]:
del stats_dict[f"Occupancy {unit}"]
del stats_dict[f"Free {unit}"]
del stats_dict[f"Clean {unit}"]
del stats_dict[f"Dirty {unit}"]
if f"Inactive Dirty {unit}" in stats_dict:
del stats_dict[f"Inactive Occupancy {unit}"]
if f"Inactive Clean {unit}" in stats_dict:
del stats_dict[f"Inactive Clean {unit}"]
if f"Inactive Dirty {unit}" in stats_dict:
del stats_dict[f"Inactive Dirty {unit}"]
def __str__(self):
return (
f"Usage stats:\n"
@ -376,13 +411,6 @@ class UsageStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.occupancy -= other.occupancy
self.free -= other.free
self.clean -= other.clean
self.dirty -= other.dirty
return self
class IoClassUsageStats:
def __init__(self, stats_dict, percentage_val):
@ -391,6 +419,11 @@ class IoClassUsageStats:
self.clean = parse_value(value=stats_dict[f"Clean {unit}"], unit_type=unit)
self.dirty = parse_value(value=stats_dict[f"Dirty {unit}"], unit_type=unit)
for unit in [UnitType.percentage, UnitType.block_4k]:
del stats_dict[f"Occupancy {unit}"]
del stats_dict[f"Clean {unit}"]
del stats_dict[f"Dirty {unit}"]
def __str__(self):
return (
f"Usage stats:\n"
@ -417,21 +450,19 @@ class IoClassUsageStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.occupancy -= other.occupancy
self.clean -= other.clean
self.dirty -= other.dirty
return self
class RequestStats:
def __init__(self, stats_dict, percentage_val):
unit = UnitType.percentage if percentage_val else UnitType.requests
self.read = RequestStatsChunk(
stats_dict=stats_dict, percentage_val=percentage_val, operation=OperationType.read
stats_dict=stats_dict,
percentage_val=percentage_val,
operation=OperationType.read,
)
self.write = RequestStatsChunk(
stats_dict=stats_dict, percentage_val=percentage_val, operation=OperationType.write
stats_dict=stats_dict,
percentage_val=percentage_val,
operation=OperationType.write,
)
self.pass_through_reads = parse_value(
value=stats_dict[f"Pass-Through reads {unit}"], unit_type=unit
@ -446,6 +477,17 @@ class RequestStats:
value=stats_dict[f"Total requests {unit}"], unit_type=unit
)
for unit in [UnitType.percentage, UnitType.requests]:
for operation in [OperationType.read, OperationType.write]:
del stats_dict[f"{operation} hits {unit}"]
del stats_dict[f"{operation} partial misses {unit}"]
del stats_dict[f"{operation} full misses {unit}"]
del stats_dict[f"{operation} total {unit}"]
del stats_dict[f"Pass-Through reads {unit}"]
del stats_dict[f"Pass-Through writes {unit}"]
del stats_dict[f"Serviced requests {unit}"]
del stats_dict[f"Total requests {unit}"]
def __str__(self):
return (
f"Request stats:\n"
@ -472,15 +514,6 @@ class RequestStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.read -= other.read
self.write -= other.write
self.pass_through_reads -= other.pass_through_reads
self.pass_through_writes -= other.pass_through_writes
self.requests_serviced -= other.requests_serviced
self.requests_total -= other.requests_total
return self
class RequestStatsChunk:
def __init__(self, stats_dict, percentage_val: bool, operation: OperationType):
@ -515,13 +548,6 @@ class RequestStatsChunk:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.hits -= other.hits
self.part_misses -= other.part_misses
self.full_misses -= other.full_misses
self.total -= other.total
return self
class BlockStats:
def __init__(self, stats_dict, percentage_val):
@ -537,6 +563,12 @@ class BlockStats:
device="exported object",
)
for unit in [UnitType.percentage, UnitType.block_4k]:
for device in ["core", "cache", "exported object"]:
del stats_dict[f"Reads from {device} {unit}"]
del stats_dict[f"Writes to {device} {unit}"]
del stats_dict[f"Total to/from {device} {unit}"]
def __str__(self):
return (
f"Block stats:\n"
@ -555,12 +587,6 @@ class BlockStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.core -= other.core
self.cache -= other.cache
self.exp_obj -= other.exp_obj
return self
class ErrorStats:
def __init__(self, stats_dict, percentage_val):
@ -573,6 +599,13 @@ class ErrorStats:
)
self.total_errors = parse_value(value=stats_dict[f"Total errors {unit}"], unit_type=unit)
for unit in [UnitType.percentage, UnitType.requests]:
for device in ["Core", "Cache"]:
del stats_dict[f"{device} read errors {unit}"]
del stats_dict[f"{device} write errors {unit}"]
del stats_dict[f"{device} total errors {unit}"]
del stats_dict[f"Total errors {unit}"]
def __str__(self):
return (
f"Error stats:\n"
@ -593,12 +626,6 @@ class ErrorStats:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.cache -= other.cache
self.core -= other.core
self.total_errors -= other.total_errors
return self
class BasicStatsChunk:
def __init__(self, stats_dict: dict, percentage_val: bool, device: str):
@ -620,12 +647,6 @@ class BasicStatsChunk:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.reads -= other.reads
self.writes -= other.writes
self.total -= other.total
return self
class BasicStatsChunkError:
def __init__(self, stats_dict: dict, percentage_val: bool, device: str):
@ -647,12 +668,6 @@ class BasicStatsChunkError:
def __iter__(self):
return iter([getattr(self, stats_item) for stats_item in self.__dict__])
def __sub__(self, other):
self.reads -= other.reads
self.writes -= other.writes
self.total -= other.total
return self
def get_stat_value(stat_dict: dict, key: str):
idx = key.index("[")
@ -698,7 +713,10 @@ def _get_section_filters(filter: List[StatsFilter], io_class_stats: bool = False
def get_stats_dict(
filter: List[StatsFilter], cache_id: int, core_id: int = None, io_class_id: int = None
filter: List[StatsFilter],
cache_id: int,
core_id: int = None,
io_class_id: int = None,
):
csv_stats = casadm.print_statistics(
cache_id=cache_id,