Skip to content

Commit

Permalink
Merge pull request #625 from arutk/mopft_21.3
Browse files Browse the repository at this point in the history
[v21.3.4] management operation power failure handling tests
  • Loading branch information
Robert Baldyga committed Dec 22, 2021
2 parents afc5b1b + 4bb4125 commit c7a66ef
Show file tree
Hide file tree
Showing 8 changed files with 797 additions and 33 deletions.
59 changes: 41 additions & 18 deletions tests/functional/pyocf/types/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ class CacheDeviceConfig(Structure):
("_uuid", Uuid),
("_volume_type", c_uint8),
("_cache_line_size", c_uint64),
("_open_cores", c_bool),
("_force", c_bool),
("_min_free_ram", c_uint64),
("_perform_test", c_bool),
("_discard_on_start", c_bool),
("_volume_params", c_void_p),
]


Expand Down Expand Up @@ -332,7 +333,9 @@ def set_seq_cut_off_promotion(self, count: int):
self.write_unlock()

if status:
raise OcfError("Error setting cache seq cut off policy promotion count", status)
raise OcfError(
"Error setting cache seq cut off policy promotion count", status
)

def get_partition_info(self, part_id: int):
ioclass_info = IoClassInfo()
Expand All @@ -347,6 +350,7 @@ def get_partition_info(self, part_id: int):
raise OcfError("Error retriving ioclass info", status)

return {
"_class_id": part_id,
"_name": ioclass_info._name.decode("ascii"),
"_cache_mode": ioclass_info._cache_mode,
"_priority": int(ioclass_info._priority),
Expand All @@ -358,7 +362,13 @@ def get_partition_info(self, part_id: int):
}

def add_partition(
self, part_id: int, name: str, min_size: int, max_size: int, priority: int, valid: bool
self,
part_id: int,
name: str,
min_size: int,
max_size: int,
priority: int,
valid: bool,
):
self.write_lock()

Expand Down Expand Up @@ -396,15 +406,15 @@ def configure_partition(
ioclasses_info._config[i]._name = (
ioclass_info._name if len(ioclass_info._name) > 0 else 0
)
ioclasses_info._config[i]._prio = ioclass_info._priority
ioclasses_info._config[i]._priority = ioclass_info._priority
ioclasses_info._config[i]._cache_mode = ioclass_info._cache_mode
ioclasses_info._config[i]._max_size = ioclass_info._max_size

self.read_unlock()

ioclasses_info._config[part_id]._name = name.encode("utf-8")
ioclasses_info._config[part_id]._cache_mode = int(cache_mode)
ioclasses_info._config[part_id]._prio = priority
ioclasses_info._config[part_id]._priority = priority
ioclasses_info._config[part_id]._max_size = max_size

self.write_lock()
Expand All @@ -419,7 +429,12 @@ def configure_partition(
raise OcfError("Error adding partition to cache", status)

def configure_device(
self, device, force=False, perform_test=True, cache_line_size=None
self,
device,
force=False,
perform_test=True,
cache_line_size=None,
open_cores=True,
):
self.device = device
self.device_name = device.uuid
Expand All @@ -430,20 +445,21 @@ def configure_device(
),
_size=len(self.device_name) + 1,
),
_volume_type=device.type_id,
_cache_line_size=cache_line_size
if cache_line_size
else self.cache_line_size,
_volume_type=device.type_id,
_open_cores=open_cores,
_force=force,
_min_free_ram=0,
_perform_test=perform_test,
_discard_on_start=False,
_volume_params=None,
)

def attach_device(
self, device, force=False, perform_test=False, cache_line_size=None
):
self.configure_device(device, force, perform_test, cache_line_size)
self.configure_device(device, force, perform_test, cache_line_size, False)
self.write_lock()

c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
Expand All @@ -463,18 +479,16 @@ def detach_device(self):

c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])

self.owner.lib.ocf_mngt_cache_detach(
self.cache_handle, c, None
)
self.owner.lib.ocf_mngt_cache_detach(self.cache_handle, c, None)

c.wait()
self.write_unlock()

if c.results["error"]:
raise OcfError("Attaching cache device failed", c.results["error"])

def load_cache(self, device):
self.configure_device(device)
def load_cache(self, device, open_cores=True):
self.configure_device(device, open_cores=open_cores)
c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)])
device.owner.lib.ocf_mngt_cache_load(
self.cache_handle, byref(self.dev_cfg), c, None
Expand All @@ -485,12 +499,12 @@ def load_cache(self, device):
raise OcfError("Loading cache device failed", c.results["error"])

@classmethod
def load_from_device(cls, device, name="cache"):
def load_from_device(cls, device, name="cache", open_cores=True):
c = cls(name=name, owner=device.owner)

c.start_cache()
try:
c.load_cache(device)
c.load_cache(device, open_cores=open_cores)
except: # noqa E722
c.stop()
raise
Expand Down Expand Up @@ -677,7 +691,8 @@ def stop(self):
self.owner.lib.ocf_mngt_cache_stop(self.cache_handle, c, None)

c.wait()
if c.results["error"]:
err = OcfErrorCode(-1 * c.results["error"])
if err != OcfErrorCode.OCF_OK and err != OcfErrorCode.OCF_ERR_WRITE_CACHE:
self.write_unlock()
raise OcfError("Failed stopping cache", c.results["error"])

Expand All @@ -689,6 +704,9 @@ def stop(self):

self.owner.caches.remove(self)

if err != OcfErrorCode.OCF_OK:
raise OcfError("Failed stopping cache", c.results["error"])

def flush(self):
self.write_lock()

Expand Down Expand Up @@ -716,7 +734,12 @@ def get_name(self):
lib.ocf_mngt_cache_add_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p]
lib.ocf_cache_get_name.argtypes = [c_void_p]
lib.ocf_cache_get_name.restype = c_char_p
lib.ocf_mngt_cache_cleaning_set_policy.argtypes = [c_void_p, c_uint32, c_void_p, c_void_p]
lib.ocf_mngt_cache_cleaning_set_policy.argtypes = [
c_void_p,
c_uint32,
c_void_p,
c_void_p,
]
lib.ocf_mngt_core_set_seq_cutoff_policy_all.argtypes = [c_void_p, c_uint32]
lib.ocf_mngt_core_set_seq_cutoff_policy_all.restype = c_int
lib.ocf_mngt_core_set_seq_cutoff_threshold_all.argtypes = [c_void_p, c_uint32]
Expand Down
1 change: 1 addition & 0 deletions tests/functional/pyocf/types/ctx.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def exit(self):
self.cleaner = None
Queue._instances_ = {}
Volume._instances_ = {}
Volume._uuid_ = {}
Data._instances_ = {}
Logger._instances_ = {}

Expand Down
3 changes: 3 additions & 0 deletions tests/functional/pyocf/types/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,6 @@ def md5(self):
m = md5()
m.update(string_at(self.handle, self.size))
return m.hexdigest()

def get_bytes(self):
return string_at(self.handle, self.size)
2 changes: 1 addition & 1 deletion tests/functional/pyocf/types/ioclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class IoClassConfig(Structure):
("_max_size", c_uint32),
("_name", c_char_p),
("_cache_mode", c_int),
("_prio", c_uint16),
("_priority", c_uint16),
]


Expand Down
1 change: 1 addition & 0 deletions tests/functional/pyocf/types/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


class OcfErrorCode(IntEnum):
OCF_OK = 0
OCF_ERR_INVAL = 1000000
OCF_ERR_AGAIN = auto()
OCF_ERR_INTR = auto()
Expand Down
68 changes: 54 additions & 14 deletions tests/functional/pyocf/types/volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def _open(ref):
return -1

if volume.opened:
return OcfErrorCode.OCF_ERR_NOT_OPEN_EXC
return -OcfErrorCode.OCF_ERR_NOT_OPEN_EXC

Volume._instances_[ref] = weakref.ref(volume)

Expand Down Expand Up @@ -269,7 +269,7 @@ def submit_discard(self, discard):

discard.contents._end(discard, 0)
except: # noqa E722
discard.contents._end(discard, -5)
discard.contents._end(discard, -OcfErrorCode.OCF_ERR_NOT_SUPP)

def get_stats(self):
return self.stats
Expand Down Expand Up @@ -299,40 +299,80 @@ def submit_io(self, io):

io.contents._end(io, 0)
except: # noqa E722
io.contents._end(io, -5)
io.contents._end(io, -OcfErrorCode.OCF_ERR_IO)

def dump(self, offset=0, size=0, ignore=VOLUME_POISON, **kwargs):
if size == 0:
size = int(self.size) - int(offset)

print_buffer(
self._storage,
size,
ignore=ignore,
**kwargs
)
print_buffer(self._storage, size, ignore=ignore, **kwargs)

def md5(self):
m = md5()
m.update(string_at(self._storage, self.size))
return m.hexdigest()

def get_bytes(self):
return string_at(self._storage, self.size)


class ErrorDevice(Volume):
def __init__(self, size, error_sectors: set = None, uuid=None):
def __init__(
self,
size,
error_sectors: set = None,
error_seq_no: dict = None,
armed=True,
uuid=None,
):
super().__init__(size, uuid)
self.error_sectors = error_sectors or set()
self.error_sectors = error_sectors
self.error_seq_no = error_seq_no
self.armed = armed
self.io_seq_no = {IoDir.WRITE: 0, IoDir.READ: 0}
self.error = False

def set_mapping(self, error_sectors: set):
self.error_sectors = error_sectors

def submit_io(self, io):
if io.contents._addr in self.error_sectors:
io.contents._end(io, -5)
self.stats["errors"][io.contents._dir] += 1
if not self.armed:
super().submit_io(io)
return

direction = IoDir(io.contents._dir)
seq_no_match = (
self.error_seq_no is not None
and direction in self.error_seq_no
and self.error_seq_no[direction] <= self.io_seq_no[direction]
)
sector_match = (
self.error_sectors is not None and io.contents._addr in self.error_sectors
)

self.io_seq_no[direction] += 1

error = True
if self.error_seq_no is not None and not seq_no_match:
error = False
if self.error_sectors is not None and not sector_match:
error = False
if error:
self.error = True
io.contents._end(io, -OcfErrorCode.OCF_ERR_IO)
self.stats["errors"][direction] += 1
else:
super().submit_io(io)

def arm(self):
self.armed = True

def disarm(self):
self.armed = False

def error_triggered(self):
return self.error

def reset_stats(self):
super().reset_stats()
self.stats["errors"] = {IoDir.WRITE: 0, IoDir.READ: 0}
Expand Down
14 changes: 14 additions & 0 deletions tests/functional/pyocf/wrappers/ocf_core_wrappers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright(c) 2021-2021 Intel Corporation
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "ocf/ocf_io.h"
#include "ocf/ocf_core.h"

const struct ocf_volume_uuid *ocf_core_get_uuid_wrapper(ocf_core_t core)
{
return ocf_core_get_uuid(core);
}


Loading

0 comments on commit c7a66ef

Please sign in to comment.