583 lines
20 KiB
Python
583 lines
20 KiB
Python
#
|
|
# Copyright(c) 2019-2022 Intel Corporation
|
|
# Copyright(c) 2024 Huawei Technologies Co., Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
from typing import List
|
|
|
|
from api.cas.cache import Cache
|
|
from api.cas.cache_config import (
|
|
CacheLineSize,
|
|
CacheMode,
|
|
SeqCutOffPolicy,
|
|
CleaningPolicy,
|
|
KernelParameters,
|
|
PromotionPolicy,
|
|
)
|
|
from api.cas.casadm_params import OutputFormat, StatsFilter
|
|
from api.cas.cli import *
|
|
from api.cas.core import Core
|
|
from core.test_run import TestRun
|
|
from storage_devices.device import Device
|
|
from test_tools.os_tools import reload_kernel_module
|
|
from connection.utils.output import CmdException, Output
|
|
from types.size import Size, Unit
|
|
|
|
|
|
# casadm commands
|
|
|
|
|
|
def start_cache(
|
|
cache_dev: Device,
|
|
cache_mode: CacheMode = None,
|
|
cache_line_size: CacheLineSize = None,
|
|
cache_id: int = None,
|
|
force: bool = False,
|
|
load: bool = False,
|
|
shortcut: bool = False,
|
|
kernel_params: KernelParameters = KernelParameters(),
|
|
) -> Cache:
|
|
if kernel_params != KernelParameters.read_current_settings():
|
|
reload_kernel_module("cas_cache", kernel_params.get_parameter_dictionary())
|
|
|
|
_cache_line_size = (
|
|
str(int(cache_line_size.value.get_value(Unit.KibiByte)))
|
|
if cache_line_size is not None
|
|
else None
|
|
)
|
|
_cache_id = str(cache_id) if cache_id is not None else None
|
|
_cache_mode = cache_mode.name.lower() if cache_mode else None
|
|
output = TestRun.executor.run(
|
|
start_cmd(
|
|
cache_dev=cache_dev.path,
|
|
cache_mode=_cache_mode,
|
|
cache_line_size=_cache_line_size,
|
|
cache_id=_cache_id,
|
|
force=force,
|
|
load=load,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to start cache.", output)
|
|
return Cache(cache_dev)
|
|
|
|
|
|
def load_cache(device: Device, shortcut: bool = False) -> Cache:
|
|
output = TestRun.executor.run(load_cmd(cache_dev=device.path, shortcut=shortcut))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to load cache.", output)
|
|
return Cache(device)
|
|
|
|
|
|
def attach_cache(cache_id: int, device: Device, force: bool, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
attach_cache_cmd(
|
|
cache_dev=device.path, cache_id=str(cache_id), force=force, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to attach cache.", output)
|
|
return output
|
|
|
|
|
|
def detach_cache(cache_id: int, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(detach_cache_cmd(cache_id=str(cache_id), shortcut=shortcut))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to detach cache.", output)
|
|
return output
|
|
|
|
|
|
def stop_cache(cache_id: int, no_data_flush: bool = False, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
stop_cmd(cache_id=str(cache_id), no_data_flush=no_data_flush, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to stop cache.", output)
|
|
return output
|
|
|
|
|
|
def set_param_cutoff(
|
|
cache_id: int,
|
|
core_id: int = None,
|
|
threshold: Size = None,
|
|
policy: SeqCutOffPolicy = None,
|
|
promotion_count: int = None,
|
|
shortcut: bool = False,
|
|
) -> Output:
|
|
_core_id = str(core_id) if core_id is not None else None
|
|
_threshold = str(int(threshold.get_value(Unit.KibiByte))) if threshold else None
|
|
_policy = policy.name if policy else None
|
|
_promotion_count = str(promotion_count) if promotion_count is not None else None
|
|
command = set_param_cutoff_cmd(
|
|
cache_id=str(cache_id),
|
|
core_id=_core_id,
|
|
threshold=_threshold,
|
|
policy=_policy,
|
|
promotion_count=_promotion_count,
|
|
shortcut=shortcut,
|
|
)
|
|
output = TestRun.executor.run(command)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting sequential cut-off params.", output)
|
|
return output
|
|
|
|
|
|
def set_param_cleaning(cache_id: int, policy: CleaningPolicy, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
set_param_cleaning_cmd(cache_id=str(cache_id), policy=policy.name, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting cleaning policy.", output)
|
|
return output
|
|
|
|
|
|
def set_param_cleaning_alru(
|
|
cache_id: int,
|
|
wake_up: int = None,
|
|
staleness_time: int = None,
|
|
flush_max_buffers: int = None,
|
|
activity_threshold: int = None,
|
|
shortcut: bool = False,
|
|
) -> Output:
|
|
_wake_up = str(wake_up) if wake_up is not None else None
|
|
_staleness_time = str(staleness_time) if staleness_time is not None else None
|
|
_flush_max_buffers = str(flush_max_buffers) if flush_max_buffers is not None else None
|
|
_activity_threshold = str(activity_threshold) if activity_threshold is not None else None
|
|
output = TestRun.executor.run(
|
|
set_param_cleaning_alru_cmd(
|
|
cache_id=str(cache_id),
|
|
wake_up=_wake_up,
|
|
staleness_time=_staleness_time,
|
|
flush_max_buffers=_flush_max_buffers,
|
|
activity_threshold=_activity_threshold,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting alru cleaning policy parameters.", output)
|
|
return output
|
|
|
|
|
|
def set_param_cleaning_acp(
|
|
cache_id: int, wake_up: int = None, flush_max_buffers: int = None, shortcut: bool = False
|
|
) -> Output:
|
|
_wake_up = str(wake_up) if wake_up is not None else None
|
|
_flush_max_buffers = str(flush_max_buffers) if flush_max_buffers is not None else None
|
|
output = TestRun.executor.run(
|
|
set_param_cleaning_acp_cmd(
|
|
cache_id=str(cache_id),
|
|
wake_up=_wake_up,
|
|
flush_max_buffers=_flush_max_buffers,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting acp cleaning policy parameters.", output)
|
|
return output
|
|
|
|
|
|
def set_param_promotion(cache_id: int, policy: PromotionPolicy, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
set_param_promotion_cmd(
|
|
cache_id=str(cache_id),
|
|
policy=policy.name,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting promotion policy.", output)
|
|
return output
|
|
|
|
|
|
def set_param_promotion_nhit(
|
|
cache_id: int, threshold: int = None, trigger: int = None, shortcut: bool = False
|
|
) -> Output:
|
|
_threshold = str(threshold) if threshold is not None else None
|
|
_trigger = str(trigger) if trigger is not None else None
|
|
output = TestRun.executor.run(
|
|
set_param_promotion_nhit_cmd(
|
|
cache_id=str(cache_id),
|
|
threshold=_threshold,
|
|
trigger=_trigger,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Error while setting promotion policy.", output)
|
|
return output
|
|
|
|
|
|
def get_param_cutoff(
|
|
cache_id: int, core_id: int, output_format: OutputFormat = None, shortcut: bool = False
|
|
) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_cutoff_cmd(
|
|
cache_id=str(cache_id),
|
|
core_id=str(core_id),
|
|
output_format=_output_format,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting sequential cutoff params failed.", output)
|
|
return output
|
|
|
|
|
|
def get_param_cleaning(cache_id: int, output_format: OutputFormat = None, shortcut: bool = False):
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_cleaning_cmd(
|
|
cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting cleaning policy failed.", output)
|
|
return output
|
|
|
|
|
|
def get_param_cleaning_alru(
|
|
cache_id: int, output_format: OutputFormat = None, shortcut: bool = False
|
|
):
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_cleaning_alru_cmd(
|
|
cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting alru cleaning policy params failed.", output)
|
|
return output
|
|
|
|
|
|
def get_param_cleaning_acp(
|
|
cache_id: int, output_format: OutputFormat = None, shortcut: bool = False
|
|
):
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_cleaning_acp_cmd(
|
|
cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting acp cleaning policy params failed.", output)
|
|
return output
|
|
|
|
|
|
def get_param_promotion(
|
|
cache_id: int, output_format: OutputFormat = None, shortcut: bool = False
|
|
) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_promotion_cmd(
|
|
cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting promotion policy failed.", output)
|
|
return output
|
|
|
|
|
|
def get_param_promotion_nhit(
|
|
cache_id: int, output_format: OutputFormat = None, shortcut: bool = False
|
|
) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
get_param_promotion_nhit_cmd(
|
|
cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Getting promotion policy nhit params failed.", output)
|
|
return output
|
|
|
|
|
|
def set_cache_mode(
|
|
cache_mode: CacheMode, cache_id: int, flush: bool = None, shortcut: bool = False
|
|
) -> Output:
|
|
flush_cache = None
|
|
if flush is not None:
|
|
flush_cache = "yes" if flush else "no"
|
|
output = TestRun.executor.run(
|
|
set_cache_mode_cmd(
|
|
cache_mode=cache_mode.name.lower(),
|
|
cache_id=str(cache_id),
|
|
flush_cache=flush_cache,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Set cache mode command failed.", output)
|
|
return output
|
|
|
|
|
|
def add_core(cache: Cache, core_dev: Device, core_id: int = None, shortcut: bool = False) -> Core:
|
|
_core_id = str(core_id) if core_id is not None else None
|
|
output = TestRun.executor.run(
|
|
add_core_cmd(
|
|
cache_id=str(cache.cache_id),
|
|
core_dev=core_dev.path,
|
|
core_id=_core_id,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to add core.", output)
|
|
return Core(core_dev.path, cache.cache_id)
|
|
|
|
|
|
def remove_core(cache_id: int, core_id: int, force: bool = False, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
remove_core_cmd(
|
|
cache_id=str(cache_id), core_id=str(core_id), force=force, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to remove core.", output)
|
|
return output
|
|
|
|
|
|
def remove_inactive(
|
|
cache_id: int, core_id: int, force: bool = False, shortcut: bool = False
|
|
) -> Output:
|
|
output = TestRun.executor.run(
|
|
remove_inactive_cmd(
|
|
cache_id=str(cache_id), core_id=str(core_id), force=force, shortcut=shortcut
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to remove inactive core.", output)
|
|
return output
|
|
|
|
|
|
def remove_detached(core_device: Device, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
remove_detached_cmd(core_device=core_device.path, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to remove detached core.", output)
|
|
return output
|
|
|
|
|
|
def list_caches(
|
|
output_format: OutputFormat = None, by_id_path: bool = True, shortcut: bool = False
|
|
) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
list_caches_cmd(output_format=_output_format, by_id_path=by_id_path, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to list caches.", output)
|
|
return output
|
|
|
|
|
|
def print_statistics(
|
|
cache_id: int,
|
|
core_id: int = None,
|
|
io_class_id: int = None,
|
|
filter: List[StatsFilter] = None,
|
|
output_format: OutputFormat = None,
|
|
by_id_path: bool = True,
|
|
io_class: bool = False,
|
|
shortcut: bool = False,
|
|
) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
_io_class_id = str(io_class_id) if io_class_id is not None else "" if io_class else None
|
|
_core_id = str(core_id) if core_id is not None else None
|
|
if filter is None:
|
|
_filter = filter
|
|
else:
|
|
names = (x.name for x in filter)
|
|
_filter = ",".join(names)
|
|
output = TestRun.executor.run(
|
|
print_statistics_cmd(
|
|
cache_id=str(cache_id),
|
|
core_id=_core_id,
|
|
io_class_id=_io_class_id,
|
|
filter=_filter,
|
|
output_format=_output_format,
|
|
by_id_path=by_id_path,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Printing statistics failed.", output)
|
|
return output
|
|
|
|
|
|
def reset_counters(cache_id: int, core_id: int = None, shortcut: bool = False) -> Output:
|
|
_core_id = str(core_id) if core_id is not None else None
|
|
output = TestRun.executor.run(
|
|
reset_counters_cmd(cache_id=str(cache_id), core_id=_core_id, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to reset counters.", output)
|
|
return output
|
|
|
|
|
|
def flush_cache(cache_id: int, shortcut: bool = False) -> Output:
|
|
command = flush_cache_cmd(cache_id=str(cache_id), shortcut=shortcut)
|
|
output = TestRun.executor.run(command)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Flushing cache failed.", output)
|
|
return output
|
|
|
|
|
|
def flush_core(cache_id: int, core_id: int, shortcut: bool = False) -> Output:
|
|
command = flush_core_cmd(cache_id=str(cache_id), core_id=str(core_id), shortcut=shortcut)
|
|
output = TestRun.executor.run(command)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Flushing core failed.", output)
|
|
return output
|
|
|
|
|
|
def load_io_classes(cache_id: int, file: str, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
load_io_classes_cmd(cache_id=str(cache_id), file=file, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Load IO class command failed.", output)
|
|
return output
|
|
|
|
|
|
def list_io_classes(cache_id: int, output_format: OutputFormat, shortcut: bool = False) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(
|
|
list_io_classes_cmd(cache_id=str(cache_id), output_format=_output_format, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("List IO class command failed.", output)
|
|
return output
|
|
|
|
|
|
def print_version(output_format: OutputFormat = None, shortcut: bool = False) -> Output:
|
|
_output_format = output_format.name if output_format else None
|
|
output = TestRun.executor.run(version_cmd(output_format=_output_format, shortcut=shortcut))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to print version.", output)
|
|
return output
|
|
|
|
|
|
def help(shortcut: bool = False) -> Output:
|
|
return TestRun.executor.run(help_cmd(shortcut))
|
|
|
|
|
|
def standby_init(
|
|
cache_dev: Device,
|
|
cache_id: int,
|
|
cache_line_size: CacheLineSize,
|
|
force: bool = False,
|
|
shortcut: bool = False,
|
|
kernel_params: KernelParameters = KernelParameters(),
|
|
) -> Cache:
|
|
if kernel_params != KernelParameters.read_current_settings():
|
|
reload_kernel_module("cas_cache", kernel_params.get_parameter_dictionary())
|
|
_cache_line_size = str(int(cache_line_size.value.get_value(Unit.KibiByte)))
|
|
|
|
output = TestRun.executor.run(
|
|
standby_init_cmd(
|
|
cache_dev=cache_dev.path,
|
|
cache_id=str(cache_id),
|
|
cache_line_size=_cache_line_size,
|
|
force=force,
|
|
shortcut=shortcut,
|
|
)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to init standby cache.", output)
|
|
return Cache(cache_dev)
|
|
|
|
|
|
def standby_load(cache_dev: Device, shortcut: bool = False) -> Cache:
|
|
output = TestRun.executor.run(standby_load_cmd(cache_dev=cache_dev.path, shortcut=shortcut))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to load standby cache.", output)
|
|
return Cache(cache_dev)
|
|
|
|
|
|
def standby_detach_cache(cache_id: int, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(standby_detach_cmd(cache_id=str(cache_id), shortcut=shortcut))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to detach standby cache.", output)
|
|
return output
|
|
|
|
|
|
def standby_activate_cache(cache_dev: Device, cache_id: int, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
standby_activate_cmd(cache_dev=cache_dev.path, cache_id=str(cache_id), shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to activate standby cache.", output)
|
|
return output
|
|
|
|
|
|
def zero_metadata(cache_dev: Device, force: bool = False, shortcut: bool = False) -> Output:
|
|
output = TestRun.executor.run(
|
|
zero_metadata_cmd(cache_dev=cache_dev.path, force=force, shortcut=shortcut)
|
|
)
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to wipe metadata.", output)
|
|
return output
|
|
|
|
|
|
# script command
|
|
|
|
|
|
def try_add(core_device: Device, cache_id: int, core_id: int) -> Core:
|
|
output = TestRun.executor.run(script_try_add_cmd(str(cache_id), core_device.path, str(core_id)))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to execute try add script command.", output)
|
|
return Core(core_device.path, cache_id)
|
|
|
|
|
|
def purge_cache(cache_id: int) -> Output:
|
|
output = TestRun.executor.run(script_purge_cache_cmd(str(cache_id)))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Purge cache failed.", output)
|
|
return output
|
|
|
|
|
|
def purge_core(cache_id: int, core_id: int) -> Output:
|
|
output = TestRun.executor.run(script_purge_core_cmd(str(cache_id), str(core_id)))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Purge core failed.", output)
|
|
return output
|
|
|
|
|
|
def detach_core(cache_id: int, core_id: int) -> Output:
|
|
output = TestRun.executor.run(script_detach_core_cmd(str(cache_id), str(core_id)))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to execute detach core script command.", output)
|
|
return output
|
|
|
|
|
|
def remove_core_with_script_command(cache_id: int, core_id: int, no_flush: bool = False) -> Output:
|
|
output = TestRun.executor.run(script_remove_core_cmd(str(cache_id), str(core_id), no_flush))
|
|
if output.exit_code != 0:
|
|
raise CmdException("Failed to execute remove core script command.", output)
|
|
return output
|
|
|
|
|
|
# casadm custom commands
|
|
|
|
|
|
def stop_all_caches() -> None:
|
|
from api.cas.casadm_parser import get_caches
|
|
|
|
caches = get_caches()
|
|
if not caches:
|
|
return
|
|
# Running "cache stop" on the reversed list to resolve the multilevel cache stop problem
|
|
for cache in reversed(caches):
|
|
stop_cache(cache_id=cache.cache_id, no_data_flush=True)
|
|
|
|
|
|
def remove_all_detached_cores() -> None:
|
|
from api.cas.casadm_parser import get_cas_devices_dict
|
|
|
|
devices = get_cas_devices_dict()
|
|
for dev in devices["core_pool"].values():
|
|
TestRun.executor.run(remove_detached_cmd(dev["device_path"]))
|