713 lines
31 KiB
Python
713 lines
31 KiB
Python
#
|
|
# Copyright(c) 2020-2021 Intel Corporation
|
|
# Copyright(c) 2024 Huawei Technologies Co., Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
from time import sleep
|
|
|
|
import pytest
|
|
|
|
from api.cas import casadm
|
|
from api.cas.cache_config import CacheMode, CacheModeTrait
|
|
from api.cas.casadm import StatsFilter
|
|
from api.cas.statistics import get_stats_dict, get_stat_value
|
|
from core.test_run import TestRun
|
|
from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan
|
|
from test_tools.fio.fio import Fio
|
|
from test_tools.fio.fio_param import ReadWrite, IoEngine
|
|
from test_utils.os_utils import Udev
|
|
from test_utils.size import Size, Unit
|
|
|
|
# One cache instance per every cache mode:
|
|
caches_count = len(CacheMode)
|
|
cores_per_cache = 4
|
|
cache_size = Size(20, Unit.GibiByte)
|
|
core_size = Size(10, Unit.GibiByte)
|
|
io_value = 1000
|
|
io_size = Size(io_value, Unit.Blocks4096)
|
|
# Error stats not included in 'stat_filter' because all of them
|
|
# should equal 0 and can be checked easier, shorter way.
|
|
default_stat_filter = [StatsFilter.usage, StatsFilter.req, StatsFilter.blk]
|
|
|
|
|
|
@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
|
|
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
|
|
def test_stats_values():
|
|
"""
|
|
title: Check for proper statistics values.
|
|
description: |
|
|
Check if CAS displays proper usage, request, block and error statistics values
|
|
for core devices in every cache mode - at the start, after IO and after cache
|
|
reload. Also check if cores' statistics match cache's statistics.
|
|
pass_criteria:
|
|
- Usage, request, block and error statistics have proper values.
|
|
- Cores' statistics match cache's statistics.
|
|
"""
|
|
|
|
with TestRun.step("Partition cache and core devices"):
|
|
cache_dev, core_dev = storage_prepare()
|
|
Udev.disable()
|
|
|
|
with TestRun.step(
|
|
f"Start {caches_count} caches (one for every cache mode) "
|
|
f"and add {cores_per_cache} cores per cache"
|
|
):
|
|
caches, cores = cache_prepare(cache_dev, core_dev)
|
|
|
|
with TestRun.step("Check initial statistics values for each core"):
|
|
check_stats_initial(caches, cores)
|
|
|
|
with TestRun.step("Run 'fio'"):
|
|
fio = fio_prepare()
|
|
for i in range(caches_count):
|
|
for j in range(cores_per_cache):
|
|
fio.add_job().target(cores[i][j].path)
|
|
fio.run()
|
|
sleep(3)
|
|
|
|
with TestRun.step("Check statistics values after IO"):
|
|
check_stats_after_io(caches, cores)
|
|
|
|
with TestRun.step("Check if cache's statistics match cores' statistics"):
|
|
check_stats_sum(caches, cores)
|
|
|
|
with TestRun.step("Stop and load caches back"):
|
|
casadm.stop_all_caches()
|
|
caches = cache_load(cache_dev)
|
|
|
|
with TestRun.step("Check statistics values after reload"):
|
|
check_stats_after_io(caches, cores, after_reload=True)
|
|
|
|
|
|
def storage_prepare():
|
|
cache_dev = TestRun.disks["cache"]
|
|
cache_parts = [cache_size] * caches_count
|
|
cache_dev.create_partitions(cache_parts)
|
|
core_dev = TestRun.disks["core"]
|
|
core_parts = [core_size] * cores_per_cache * caches_count
|
|
core_dev.create_partitions(core_parts)
|
|
|
|
return cache_dev, core_dev
|
|
|
|
|
|
def cache_prepare(cache_dev, core_dev):
|
|
caches = []
|
|
for i, cache_mode in enumerate(CacheMode):
|
|
caches.append(
|
|
casadm.start_cache(cache_dev.partitions[i], cache_mode, force=True)
|
|
)
|
|
cores = [[] for _ in range(caches_count)]
|
|
for i in range(caches_count):
|
|
for j in range(cores_per_cache):
|
|
core_partition_number = i * cores_per_cache + j
|
|
cores[i].append(caches[i].add_core(core_dev.partitions[core_partition_number]))
|
|
|
|
return caches, cores
|
|
|
|
|
|
def cache_load(cache_dev):
|
|
caches = []
|
|
for i in range(caches_count):
|
|
caches.append(casadm.load_cache(cache_dev.partitions[i]))
|
|
|
|
return caches
|
|
|
|
|
|
def fio_prepare():
|
|
fio = (
|
|
Fio()
|
|
.create_command()
|
|
.io_engine(IoEngine.libaio)
|
|
.read_write(ReadWrite.randwrite)
|
|
.size(io_size)
|
|
.direct()
|
|
)
|
|
|
|
return fio
|
|
|
|
|
|
def get_stats(stat_filter, cores, cache=None):
|
|
cores_stats = [
|
|
get_stats_dict(
|
|
filter=stat_filter, cache_id=cores[j].cache_id, core_id=cores[j].core_id
|
|
) for j in range(cores_per_cache)
|
|
]
|
|
cores_stats_perc = [
|
|
{k: get_stat_value(cores_stats[j], k) for k in cores_stats[j] if k.endswith("[%]")}
|
|
for j in range(cores_per_cache)
|
|
]
|
|
cores_stats_values = [
|
|
{k: get_stat_value(cores_stats[j], k) for k in cores_stats[j] if not k.endswith("[%]")}
|
|
for j in range(cores_per_cache)
|
|
]
|
|
|
|
if cache:
|
|
cache_stats = get_stats_dict(filter=stat_filter, cache_id=cache.cache_id)
|
|
cache_stats_values = {
|
|
k: get_stat_value(cache_stats, k) for k in cache_stats if not k.endswith("[%]")
|
|
}
|
|
return cores_stats_values, cores_stats_perc, cache_stats_values
|
|
else:
|
|
return cores_stats_values, cores_stats_perc
|
|
|
|
|
|
def check_stats_initial(caches, cores):
|
|
for i in range(caches_count):
|
|
cores_stats, cores_stats_perc = get_stats(stat_filter=default_stat_filter, cores=cores[i])
|
|
for j in range(cores_per_cache):
|
|
for stat_name, stat_value in cores_stats[j].items():
|
|
try:
|
|
stat_value = stat_value.value
|
|
except AttributeError:
|
|
pass
|
|
if stat_name.startswith("Free"):
|
|
if stat_value != caches[i].size.value:
|
|
TestRun.LOGGER.error(
|
|
f"For core device {cores[i][j].path} "
|
|
f"value for '{stat_name}' is {stat_value}, "
|
|
f"should equal cache size: {caches[i].size.value}\n")
|
|
elif stat_value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"For core device {cores[i][j].path} value for "
|
|
f"'{stat_name}' is {stat_value}, should equal 0\n")
|
|
for stat_name, stat_value in cores_stats_perc[j].items():
|
|
if stat_name.startswith("Free"):
|
|
if stat_value != 100:
|
|
TestRun.LOGGER.error(
|
|
f"For core device {cores[i][j].path} percentage value "
|
|
f"for '{stat_name}' is {stat_value}, should equal 100\n")
|
|
elif stat_value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"For core device {cores[i][j].path} percentage value "
|
|
f"for '{stat_name}' is {stat_value}, should equal 0\n")
|
|
|
|
|
|
def check_stats_after_io(caches, cores, after_reload: bool = False):
|
|
for i in range(caches_count):
|
|
cache_mode = caches[i].get_cache_mode()
|
|
cores_stats = [
|
|
cores[i][j].get_statistics(stat_filter=default_stat_filter)
|
|
for j in range(cores_per_cache)
|
|
]
|
|
cores_stats_perc = [
|
|
cores[i][j].get_statistics(stat_filter=default_stat_filter, percentage_val=True)
|
|
for j in range(cores_per_cache)
|
|
]
|
|
cores_error_stats, cores_error_stats_perc = get_stats(
|
|
stat_filter=[StatsFilter.err], cores=cores[i]
|
|
)
|
|
for j in range(cores_per_cache):
|
|
fail_message = (
|
|
f"For core device {cores[i][j].path} in {cache_mode} cache mode ")
|
|
if after_reload:
|
|
validate_usage_stats(
|
|
cores_stats[j], cores_stats_perc[j], caches[i], cache_mode, fail_message)
|
|
validate_error_stats(
|
|
cores_error_stats[j], cores_error_stats_perc[j], fail_message)
|
|
else:
|
|
validate_usage_stats(
|
|
cores_stats[j], cores_stats_perc[j], caches[i], cache_mode, fail_message)
|
|
validate_request_stats(
|
|
cores_stats[j], cores_stats_perc[j], cache_mode, fail_message)
|
|
validate_block_stats(
|
|
cores_stats[j], cores_stats_perc[j], cache_mode, fail_message)
|
|
validate_error_stats(
|
|
cores_error_stats[j], cores_error_stats_perc[j], fail_message)
|
|
|
|
|
|
def check_stats_sum(caches, cores):
|
|
for i in range(caches_count):
|
|
cores_stats, cores_stats_perc, cache_stats = (
|
|
get_stats(stat_filter=default_stat_filter, cores=cores[i], cache=caches[i])
|
|
)
|
|
for stat_name in cache_stats.keys():
|
|
if stat_name.startswith("Free"):
|
|
continue
|
|
core_stat_sum = 0
|
|
try:
|
|
cache_stats[stat_name] = cache_stats[stat_name].value
|
|
for j in range(cores_per_cache):
|
|
cores_stats[j][stat_name] = cores_stats[j][stat_name].value
|
|
except AttributeError:
|
|
pass
|
|
for j in range(cores_per_cache):
|
|
core_stat_sum += cores_stats[j][stat_name]
|
|
if core_stat_sum != cache_stats[stat_name]:
|
|
TestRun.LOGGER.error(
|
|
f"For cache ID {caches[i].cache_id} sum of cores' "
|
|
f"'{stat_name}' values is {core_stat_sum}, "
|
|
f"should equal {cache_stats[stat_name]}\n")
|
|
|
|
|
|
def validate_usage_stats(stats, stats_perc, cache, cache_mode, fail_message):
|
|
fail_message += f"in 'usage' stats"
|
|
if cache_mode not in CacheMode.with_traits(CacheModeTrait.InsertWrite):
|
|
if stats.usage_stats.occupancy.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'occupancy' is "
|
|
f"{stats.usage_stats.occupancy.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.usage_stats.occupancy != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'occupancy' percentage is "
|
|
f"{stats_perc.usage_stats.occupancy}, "
|
|
f"should equal 0\n")
|
|
if stats.usage_stats.free != cache.size:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'free' is "
|
|
f"{stats.usage_stats.free.value}, "
|
|
f"should equal cache size: {cache.size.value}\n")
|
|
if stats_perc.usage_stats.free != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'free' percentage is "
|
|
f"{stats_perc.usage_stats.free}, "
|
|
f"should equal 100\n")
|
|
if stats.usage_stats.clean.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' is "
|
|
f"{stats.usage_stats.clean.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.usage_stats.clean != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' percentage is "
|
|
f"{stats_perc.usage_stats.clean}, "
|
|
f"should equal 0\n")
|
|
if stats.usage_stats.dirty.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' is "
|
|
f"{stats.usage_stats.dirty.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.usage_stats.dirty != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' percentage is "
|
|
f"{stats_perc.usage_stats.dirty}, "
|
|
f"should equal 0\n")
|
|
else:
|
|
occupancy_perc = round(100 * io_size.value / cache.size.value, 1)
|
|
free = cache.size.value - io_size.value * cores_per_cache
|
|
free_perc = round(100 * (cache.size.value - io_size.value
|
|
* cores_per_cache) / cache.size.value, 1)
|
|
if stats.usage_stats.occupancy.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'occupancy' is "
|
|
f"{stats.usage_stats.occupancy.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.usage_stats.occupancy != occupancy_perc:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'occupancy' percentage is "
|
|
f"{stats_perc.usage_stats.occupancy}, "
|
|
f"should equal {occupancy_perc}\n")
|
|
if stats.usage_stats.free.value != free:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'free' is "
|
|
f"{stats.usage_stats.free.value}, "
|
|
f"should equal {free}\n")
|
|
if stats_perc.usage_stats.free != free_perc:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'free' percentage is "
|
|
f"{stats_perc.usage_stats.free}, "
|
|
f"should equal {free_perc}\n")
|
|
if cache_mode not in CacheMode.with_traits(CacheModeTrait.LazyWrites):
|
|
if stats.usage_stats.clean.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' is "
|
|
f"{stats.usage_stats.clean.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.usage_stats.clean != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' percentage is "
|
|
f"{stats_perc.usage_stats.clean}, "
|
|
f"should equal 100\n")
|
|
if stats.usage_stats.dirty.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' is "
|
|
f"{stats.usage_stats.dirty.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.usage_stats.dirty != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' percentage is "
|
|
f"{stats_perc.usage_stats.dirty}, "
|
|
f"should equal 0\n")
|
|
else:
|
|
if stats.usage_stats.clean.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' is "
|
|
f"{stats.usage_stats.clean.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.usage_stats.clean != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'clean' percentage is "
|
|
f"{stats_perc.usage_stats.clean}, "
|
|
f"should equal 0\n")
|
|
if stats.usage_stats.dirty.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' is "
|
|
f"{stats.usage_stats.dirty.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.usage_stats.dirty != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'dirty' percentage is "
|
|
f"{stats_perc.usage_stats.dirty}, "
|
|
f"should equal 100\n")
|
|
|
|
|
|
def validate_request_stats(stats, stats_perc, cache_mode, fail_message):
|
|
fail_message += f"in 'request' stats"
|
|
if stats.request_stats.read.hits != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read hits' is "
|
|
f"{stats.request_stats.read.hits}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.read.hits != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read hits' percentage is "
|
|
f"{stats_perc.request_stats.read.hits}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.read.part_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read partial misses' is "
|
|
f"{stats.request_stats.read.part_misses}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.read.part_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read partial misses' percentage is "
|
|
f"{stats_perc.request_stats.read.part_misses}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.read.full_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read full misses' is "
|
|
f"{stats.request_stats.read.full_misses}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.read.full_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read full misses' percentage is "
|
|
f"{stats_perc.request_stats.read.full_misses}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.read.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read total' is "
|
|
f"{stats.request_stats.read.total}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.read.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Read total' percentage is "
|
|
f"{stats_perc.request_stats.read.total}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.write.hits != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write hits' is "
|
|
f"{stats.request_stats.write.hits}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.write.hits != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write hits' percentage is "
|
|
f"{stats_perc.request_stats.write.hits}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.write.part_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write partial misses' is "
|
|
f"{stats.request_stats.write.part_misses}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.write.part_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write partial misses' percentage is "
|
|
f"{stats_perc.request_stats.write.part_misses}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.pass_through_reads != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through reads' is "
|
|
f"{stats.request_stats.pass_through_reads}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.pass_through_reads != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through reads' percentage is "
|
|
f"{stats_perc.request_stats.pass_through_reads}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.requests_total != io_value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Total requests' is "
|
|
f"{stats.request_stats.requests_total}, "
|
|
f"should equal IO size value: {io_value}\n")
|
|
if stats_perc.request_stats.requests_total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Total requests' percentage is "
|
|
f"{stats_perc.request_stats.requests_total}, "
|
|
f"should equal 100\n")
|
|
if cache_mode in CacheMode.with_traits(CacheModeTrait.InsertWrite):
|
|
if stats.request_stats.write.full_misses != io_value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write full misses' is "
|
|
f"{stats.request_stats.write.full_misses}, "
|
|
f"should equal IO size value: {io_value}\n")
|
|
if stats_perc.request_stats.write.full_misses != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write full misses' percentage is "
|
|
f"{stats_perc.request_stats.write.full_misses}, "
|
|
f"should equal 100\n")
|
|
if stats.request_stats.write.total != io_value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write total' is "
|
|
f"{stats.request_stats.write.total}, "
|
|
f"should equal IO size value: {io_value}\n")
|
|
if stats_perc.request_stats.write.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write total' percentage is "
|
|
f"{stats_perc.request_stats.write.total}, "
|
|
f"should equal 100\n")
|
|
if stats.request_stats.pass_through_writes != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through writes' is "
|
|
f"{stats.request_stats.pass_through_writes}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.pass_through_writes != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through writes' percentage is "
|
|
f"{stats_perc.request_stats.pass_through_writes}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.requests_serviced != io_value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Serviced requests' is "
|
|
f"{stats.request_stats.requests_serviced}, "
|
|
f"should equal IO size value: {io_value}\n")
|
|
if stats_perc.request_stats.requests_serviced != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Serviced requests' percentage is "
|
|
f"{stats_perc.request_stats.requests_serviced}, "
|
|
f"should equal 100\n")
|
|
else:
|
|
if stats.request_stats.write.full_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write full misses' is "
|
|
f"{stats.request_stats.write.full_misses}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.write.full_misses != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write full misses' percentage is "
|
|
f"{stats_perc.request_stats.write.full_misses}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.write.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write total' is "
|
|
f"{stats.request_stats.write.total}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.write.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Write total' percentage is "
|
|
f"{stats_perc.request_stats.write.total}, "
|
|
f"should equal 0\n")
|
|
if stats.request_stats.pass_through_writes != io_value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through writes' is "
|
|
f"{stats.request_stats.pass_through_writes}, "
|
|
f"should equal IO size value: {io_value}\n")
|
|
if stats_perc.request_stats.pass_through_writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Pass-through writes' percentage is "
|
|
f"{stats_perc.request_stats.pass_through_writes}, "
|
|
f"should equal 100\n")
|
|
if stats.request_stats.requests_serviced != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Serviced requests' is "
|
|
f"{stats.request_stats.requests_serviced}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.request_stats.requests_serviced != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Serviced requests' percentage is "
|
|
f"{stats_perc.request_stats.requests_serviced}, "
|
|
f"should equal 0\n")
|
|
|
|
|
|
def validate_block_stats(stats, stats_perc, cache_mode, fail_message):
|
|
fail_message += f"in 'block' stats"
|
|
if stats.block_stats.core.reads.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core reads' is "
|
|
f"{stats.block_stats.core.reads.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.core.reads != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core reads' percentage is "
|
|
f"{stats_perc.block_stats.core.reads}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.cache.reads.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache reads' is "
|
|
f"{stats.block_stats.cache.reads.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.cache.reads != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache reads' percentage is "
|
|
f"{stats_perc.block_stats.cache.reads}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.exp_obj.reads.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object reads' is "
|
|
f"{stats.block_stats.exp_obj.reads.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.exp_obj.reads != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object reads' percentage is "
|
|
f"{stats_perc.block_stats.exp_obj.reads}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.exp_obj.writes.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object writes' is "
|
|
f"{stats.block_stats.exp_obj.writes.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.exp_obj.writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object writes' percentage is "
|
|
f"{stats_perc.block_stats.exp_obj.writes}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.exp_obj.total.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object total' is "
|
|
f"{stats.block_stats.exp_obj.total.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.exp_obj.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Exported object total' percentage is "
|
|
f"{stats_perc.block_stats.exp_obj.total}, "
|
|
f"should equal 100\n")
|
|
if cache_mode not in CacheMode.with_traits(CacheModeTrait.InsertWrite):
|
|
if stats.block_stats.core.writes.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' is "
|
|
f"{stats.block_stats.core.writes.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.core.writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' percentage is "
|
|
f"{stats_perc.block_stats.core.writes}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.core.total.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' is "
|
|
f"{stats.block_stats.core.total.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.core.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' percentage is "
|
|
f"{stats_perc.block_stats.core.total}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.cache.writes.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' is "
|
|
f"{stats.block_stats.cache.writes.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.cache.writes != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' percentage is "
|
|
f"{stats_perc.block_stats.cache.writes}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.cache.total.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' is "
|
|
f"{stats.block_stats.cache.total.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.cache.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' percentage is "
|
|
f"{stats_perc.block_stats.cache.total}, "
|
|
f"should equal 0\n")
|
|
elif cache_mode in CacheMode.with_traits(
|
|
CacheModeTrait.InsertWrite | CacheModeTrait.LazyWrites
|
|
):
|
|
if stats.block_stats.core.writes.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' is "
|
|
f"{stats.block_stats.core.writes.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.core.writes != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' percentage is "
|
|
f"{stats_perc.block_stats.core.writes}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.core.total.value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' is "
|
|
f"{stats.block_stats.core.total.value}, "
|
|
f"should equal 0\n")
|
|
if stats_perc.block_stats.core.total != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' percentage is "
|
|
f"{stats_perc.block_stats.core.total}, "
|
|
f"should equal 0\n")
|
|
if stats.block_stats.cache.writes.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' is "
|
|
f"{stats.block_stats.cache.writes.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.cache.writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' percentage is "
|
|
f"{stats_perc.block_stats.cache.writes}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.cache.total.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' is "
|
|
f"{stats.block_stats.cache.total.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.cache.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' percentage is "
|
|
f"{stats_perc.block_stats.cache.total}, "
|
|
f"should equal 100\n")
|
|
elif (
|
|
cache_mode in CacheMode.with_traits(CacheModeTrait.InsertWrite)
|
|
and cache_mode not in CacheMode.with_traits(CacheModeTrait.LazyWrites)
|
|
):
|
|
if stats.block_stats.core.writes.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' is "
|
|
f"{stats.block_stats.core.writes.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.core.writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core writes' percentage is "
|
|
f"{stats_perc.block_stats.core.writes}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.core.total.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' is "
|
|
f"{stats.block_stats.core.total.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.core.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Core total' percentage is "
|
|
f"{stats_perc.block_stats.core.total}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.cache.writes.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' is "
|
|
f"{stats.block_stats.cache.writes.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.cache.writes != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache writes' percentage is "
|
|
f"{stats_perc.block_stats.cache.writes}, "
|
|
f"should equal 100\n")
|
|
if stats.block_stats.cache.total.value != io_size.value:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' is "
|
|
f"{stats.block_stats.cache.total.value}, "
|
|
f"should equal IO size: {io_size.value}\n")
|
|
if stats_perc.block_stats.cache.total != 100:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} 'Cache total' percentage is "
|
|
f"{stats_perc.block_stats.cache.total}, "
|
|
f"should equal 100\n")
|
|
|
|
|
|
def validate_error_stats(stats, stats_perc, fail_message):
|
|
fail_message += f"in 'error' stats"
|
|
for stat_name, stat_value in stats.items():
|
|
if stat_value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} '{stat_name}' is {stat_value}, should equal 0\n")
|
|
for stat_name, stat_value in stats_perc.items():
|
|
if stat_value != 0:
|
|
TestRun.LOGGER.error(
|
|
f"{fail_message} '{stat_name}' percentage is {stat_value}, should equal 0\n")
|