Changes after review
Signed-off-by: Daniel Madej <daniel.madej@intel.com>
This commit is contained in:
parent
830bcfd1b0
commit
695d9a688f
@ -4,10 +4,11 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import enum
|
import enum
|
||||||
|
import functools
|
||||||
|
import random
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from random import randint, randrange
|
|
||||||
|
|
||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ MAX_CLASSIFICATION_DELAY = timedelta(seconds=6)
|
|||||||
IO_CLASS_CONFIG_HEADER = "IO class id,IO class name,Eviction priority,Allocation"
|
IO_CLASS_CONFIG_HEADER = "IO class id,IO class name,Eviction priority,Allocation"
|
||||||
|
|
||||||
|
|
||||||
|
@functools.total_ordering
|
||||||
class IoClass:
|
class IoClass:
|
||||||
def __init__(self, class_id: int, rule: str = '', priority: int = None,
|
def __init__(self, class_id: int, rule: str = '', priority: int = None,
|
||||||
allocation: bool = True):
|
allocation: bool = True):
|
||||||
@ -37,8 +39,12 @@ class IoClass:
|
|||||||
f',{int(self.allocation)}')
|
f',{int(self.allocation)}')
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return type(other) is IoClass and self.id == other.id and self.rule == other.rule \
|
return ((self.id, self.rule, self.priority, self.allocation)
|
||||||
and self.priority == other.priority and self.allocation == other.allocation
|
== (other.id, other.rule, other.priority, other.allocation))
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return ((self.id, self.rule, self.priority, self.allocation)
|
||||||
|
< (other.id, other.rule, other.priority, other.allocation))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_string(ioclass_str: str):
|
def from_string(ioclass_str: str):
|
||||||
@ -75,63 +81,45 @@ class IoClass:
|
|||||||
IoClass.list_to_csv(ioclass_list, add_default_rule))
|
IoClass.list_to_csv(ioclass_list, add_default_rule))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default():
|
def default(priority: int = 255, allocation: bool = True):
|
||||||
return IoClass(0, 'unclassified', 255)
|
return IoClass(0, 'unclassified', priority, allocation)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def compare_ioclass_lists(list1: [], list2: []):
|
def compare_ioclass_lists(list1: [], list2: []):
|
||||||
if len(list1) != len(list2):
|
return sorted(list1) == sorted(list2)
|
||||||
return False
|
|
||||||
sorted_list1 = sorted(list1, key=lambda c: (c.id, c.priority, c.allocation))
|
|
||||||
sorted_list2 = sorted(list2, key=lambda c: (c.id, c.priority, c.allocation))
|
|
||||||
for i in range(len(list1)):
|
|
||||||
if sorted_list1[i] != sorted_list2[i]:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_random_ioclass_list(count: int, max_priority: int = MAX_IO_CLASS_PRIORITY):
|
def generate_random_ioclass_list(count: int, max_priority: int = MAX_IO_CLASS_PRIORITY):
|
||||||
random_list = [IoClass.default().set_priority(randint(0, max_priority))
|
random_list = [IoClass.default(priority=random.randint(0, max_priority),
|
||||||
.set_allocation(bool(randint(0, 1)))]
|
allocation=bool(random.randint(0, 1)))]
|
||||||
for i in range(1, count):
|
for i in range(1, count):
|
||||||
random_list.append(IoClass(i).set_random_rule().set_priority(randint(0, max_priority))
|
random_list.append(IoClass(i, priority=random.randint(0, max_priority),
|
||||||
.set_allocation(bool(randint(0, 1))))
|
allocation=bool(random.randint(0, 1)))
|
||||||
|
.set_random_rule())
|
||||||
return random_list
|
return random_list
|
||||||
|
|
||||||
def set_priority(self, priority: int):
|
|
||||||
self.priority = priority
|
|
||||||
return self
|
|
||||||
|
|
||||||
def set_allocation(self, allocation: bool):
|
|
||||||
self.allocation = allocation
|
|
||||||
return self
|
|
||||||
|
|
||||||
def set_rule(self, rule: str):
|
|
||||||
self.rule = rule
|
|
||||||
return self
|
|
||||||
|
|
||||||
def set_random_rule(self):
|
def set_random_rule(self):
|
||||||
rules = ["metadata", "direct", "file_size", "directory", "io_class", "extension", "lba",
|
rules = ["metadata", "direct", "file_size", "directory", "io_class", "extension", "lba",
|
||||||
"pid", "process_name", "file_offset", "request_size"]
|
"pid", "process_name", "file_offset", "request_size"]
|
||||||
if os_utils.get_kernel_version() >= version.Version("4.13"):
|
if os_utils.get_kernel_version() >= version.Version("4.13"):
|
||||||
rules.append("wlth")
|
rules.append("wlth")
|
||||||
|
|
||||||
rule = rules[randrange(len(rules))]
|
rule = random.choice(rules)
|
||||||
self.set_rule(IoClass.add_random_params(rule))
|
self.rule = IoClass.add_random_params(rule)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_random_params(rule: str):
|
def add_random_params(rule: str):
|
||||||
if rule == "directory":
|
if rule == "directory":
|
||||||
rule += \
|
allowed_chars = string.ascii_letters + string.digits + '/'
|
||||||
f":/{random_string(randint(1, 40), string.ascii_letters + string.digits + '/')}"
|
rule += f":/{random_string(random.randint(1, 40), allowed_chars)}"
|
||||||
elif rule in ["file_size", "lba", "pid", "file_offset", "request_size", "wlth"]:
|
elif rule in ["file_size", "lba", "pid", "file_offset", "request_size", "wlth"]:
|
||||||
rule += f":{Operator(randrange(len(Operator))).name}:{randrange(1000000)}"
|
rule += f":{Operator(random.randrange(len(Operator))).name}:{random.randrange(1000000)}"
|
||||||
elif rule == "io_class":
|
elif rule == "io_class":
|
||||||
rule += f":{randrange(MAX_IO_CLASS_PRIORITY + 1)}"
|
rule += f":{random.randrange(MAX_IO_CLASS_PRIORITY + 1)}"
|
||||||
elif rule in ["extension", "process_name"]:
|
elif rule in ["extension", "process_name"]:
|
||||||
rule += f":{random_string(randint(1, 10))}"
|
rule += f":{random_string(random.randint(1, 10))}"
|
||||||
if randrange(2):
|
if random.randrange(2):
|
||||||
rule += "&done"
|
rule += "&done"
|
||||||
return rule
|
return rule
|
||||||
|
|
||||||
|
@ -24,15 +24,16 @@ ioclass_config_path = "/tmp/opencas_ioclass.conf"
|
|||||||
def test_ioclass_export_configuration(cache_mode):
|
def test_ioclass_export_configuration(cache_mode):
|
||||||
"""
|
"""
|
||||||
title: Export IO class configuration to a file
|
title: Export IO class configuration to a file
|
||||||
description: Test CAS ability to create a properly formatted file with current IO class
|
description: |
|
||||||
configuration
|
Test CAS ability to create a properly formatted file with current IO class configuration
|
||||||
pass_criteria:
|
pass_criteria:
|
||||||
- CAS default IO class configuration contains unclassified class only
|
- CAS default IO class configuration contains unclassified class only
|
||||||
- CAS properly imports previously exported configuration
|
- CAS properly imports previously exported configuration
|
||||||
"""
|
"""
|
||||||
cache, core = prepare(cache_mode)
|
with TestRun.LOGGER.step(f"Test prepare"):
|
||||||
saved_config_path = "/tmp/opencas_saved.conf"
|
cache, core = prepare(cache_mode)
|
||||||
default_list = [IoClass.default()]
|
saved_config_path = "/tmp/opencas_saved.conf"
|
||||||
|
default_list = [IoClass.default()]
|
||||||
|
|
||||||
with TestRun.LOGGER.step(f"Check IO class configuration (should contain only default class)"):
|
with TestRun.LOGGER.step(f"Check IO class configuration (should contain only default class)"):
|
||||||
csv = casadm.list_io_classes(cache.cache_id, OutputFormat.csv).stdout
|
csv = casadm.list_io_classes(cache.cache_id, OutputFormat.csv).stdout
|
||||||
@ -82,7 +83,8 @@ def test_ioclass_export_configuration(cache_mode):
|
|||||||
f"Current:\n{csv}\n"
|
f"Current:\n{csv}\n"
|
||||||
f"Expected:{IoClass.list_to_csv(random_list)}")
|
f"Expected:{IoClass.list_to_csv(random_list)}")
|
||||||
|
|
||||||
fs_utils.remove(saved_config_path)
|
with TestRun.LOGGER.step(f"Test cleanup"):
|
||||||
|
fs_utils.remove(saved_config_path)
|
||||||
|
|
||||||
|
|
||||||
def prepare(cache_mode: CacheMode = None):
|
def prepare(cache_mode: CacheMode = None):
|
||||||
|
Loading…
Reference in New Issue
Block a user