Changes after review

Signed-off-by: Daniel Madej <daniel.madej@intel.com>
This commit is contained in:
Daniel Madej 2019-11-06 17:29:29 +01:00 committed by Robert Baldyga
parent 830bcfd1b0
commit 695d9a688f
2 changed files with 34 additions and 44 deletions

View File

@ -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

View File

@ -24,12 +24,13 @@ 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
""" """
with TestRun.LOGGER.step(f"Test prepare"):
cache, core = prepare(cache_mode) cache, core = prepare(cache_mode)
saved_config_path = "/tmp/opencas_saved.conf" saved_config_path = "/tmp/opencas_saved.conf"
default_list = [IoClass.default()] default_list = [IoClass.default()]
@ -82,6 +83,7 @@ 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)}")
with TestRun.LOGGER.step(f"Test cleanup"):
fs_utils.remove(saved_config_path) fs_utils.remove(saved_config_path)