pyocf: Update tests after the API changes
Signed-off-by: Robert Baldyga <robert.baldyga@huawei.com> Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
This commit is contained in:
parent
c5741df0ed
commit
be0ad8fe20
@ -88,19 +88,13 @@ class VolumeOps(Structure):
|
|||||||
class VolumeProperties(Structure):
|
class VolumeProperties(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
("_name", c_char_p),
|
("_name", c_char_p),
|
||||||
("_io_priv_size", c_uint32),
|
|
||||||
("_volume_priv_size", c_uint32),
|
("_volume_priv_size", c_uint32),
|
||||||
("_caps", VolumeCaps),
|
("_caps", VolumeCaps),
|
||||||
("_io_ops", IoOps),
|
|
||||||
("_deinit", c_char_p),
|
("_deinit", c_char_p),
|
||||||
("_ops_", VolumeOps),
|
("_ops_", VolumeOps),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class VolumeIoPriv(Structure):
|
|
||||||
_fields_ = [("_data", c_void_p), ("_offset", c_uint64)]
|
|
||||||
|
|
||||||
|
|
||||||
VOLUME_POISON = 0x13
|
VOLUME_POISON = 0x13
|
||||||
|
|
||||||
|
|
||||||
@ -243,11 +237,9 @@ class Volume:
|
|||||||
|
|
||||||
Volume._props_[cls] = VolumeProperties(
|
Volume._props_[cls] = VolumeProperties(
|
||||||
_name=str(cls.__name__).encode("ascii"),
|
_name=str(cls.__name__).encode("ascii"),
|
||||||
_io_priv_size=sizeof(VolumeIoPriv),
|
|
||||||
_volume_priv_size=0,
|
_volume_priv_size=0,
|
||||||
_caps=VolumeCaps(_atomic_writes=0),
|
_caps=VolumeCaps(_atomic_writes=0),
|
||||||
_ops_=cls.get_ops(),
|
_ops_=cls.get_ops(),
|
||||||
_io_ops=cls.get_io_ops(),
|
|
||||||
_deinit=0,
|
_deinit=0,
|
||||||
)
|
)
|
||||||
return Volume._props_[cls]
|
return Volume._props_[cls]
|
||||||
@ -267,22 +259,6 @@ class Volume:
|
|||||||
def get_by_uuid(cls, uuid):
|
def get_by_uuid(cls, uuid):
|
||||||
return cls._uuid_[uuid]
|
return cls._uuid_[uuid]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@IoOps.SET_DATA
|
|
||||||
def _io_set_data(io, data, offset):
|
|
||||||
io_priv = cast(OcfLib.getInstance().ocf_io_get_priv(io), POINTER(VolumeIoPriv))
|
|
||||||
data = Data.get_instance(data)
|
|
||||||
io_priv.contents._offset = offset
|
|
||||||
io_priv.contents._data = data.handle
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@IoOps.GET_DATA
|
|
||||||
def _io_get_data(io):
|
|
||||||
io_priv = cast(OcfLib.getInstance().ocf_io_get_priv(io), POINTER(VolumeIoPriv))
|
|
||||||
return io_priv.contents._data
|
|
||||||
|
|
||||||
def __init__(self, uuid=None):
|
def __init__(self, uuid=None):
|
||||||
if uuid:
|
if uuid:
|
||||||
if uuid in type(self)._uuid_:
|
if uuid in type(self)._uuid_:
|
||||||
@ -499,8 +475,7 @@ class RamVolume(Volume):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
io_priv = cast(OcfLib.getInstance().ocf_io_get_priv(io), POINTER(VolumeIoPriv))
|
offset = OcfLib.getInstance().ocf_io_get_offset(io)
|
||||||
offset = io_priv.contents._offset
|
|
||||||
|
|
||||||
if io.contents._dir == IoDir.WRITE:
|
if io.contents._dir == IoDir.WRITE:
|
||||||
src_ptr = cast(OcfLib.getInstance().ocf_io_get_data(io), c_void_p)
|
src_ptr = cast(OcfLib.getInstance().ocf_io_get_data(io), c_void_p)
|
||||||
@ -512,7 +487,6 @@ class RamVolume(Volume):
|
|||||||
src = self.data_ptr + io.contents._addr
|
src = self.data_ptr + io.contents._addr
|
||||||
|
|
||||||
memmove(dst, src, io.contents._bytes)
|
memmove(dst, src, io.contents._bytes)
|
||||||
io_priv.contents._offset += io.contents._bytes
|
|
||||||
|
|
||||||
io.contents._end(io, 0)
|
io.contents._end(io, 0)
|
||||||
except: # noqa E722
|
except: # noqa E722
|
||||||
@ -597,7 +571,6 @@ class ErrorDevice(Volume):
|
|||||||
def should_forward_io(self, rw, addr):
|
def should_forward_io(self, rw, addr):
|
||||||
if not self.armed:
|
if not self.armed:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
direction = IoDir(rw)
|
direction = IoDir(rw)
|
||||||
seq_no_match = (
|
seq_no_match = (
|
||||||
self.error_seq_no[direction] >= 0
|
self.error_seq_no[direction] >= 0
|
||||||
@ -633,7 +606,7 @@ class ErrorDevice(Volume):
|
|||||||
else:
|
else:
|
||||||
self.complete_submit_with_error(io)
|
self.complete_submit_with_error(io)
|
||||||
|
|
||||||
def complete_forward_with_error(self, token, rw):
|
def complete_forward_with_error(self, token, rw=IoDir.WRITE):
|
||||||
self.error = True
|
self.error = True
|
||||||
direction = IoDir(rw)
|
direction = IoDir(rw)
|
||||||
self.stats["errors"][direction] += 1
|
self.stats["errors"][direction] += 1
|
||||||
@ -646,16 +619,16 @@ class ErrorDevice(Volume):
|
|||||||
self.complete_forward_with_error(token, rw)
|
self.complete_forward_with_error(token, rw)
|
||||||
|
|
||||||
def do_forward_flush(self, token):
|
def do_forward_flush(self, token):
|
||||||
if self.data_only or self.should_forward_io(0, 0):
|
if self.data_only or self.should_forward_io(IoDir.WRITE, 0):
|
||||||
self.vol.do_forward_flush(token)
|
self.vol.do_forward_flush(token)
|
||||||
else:
|
else:
|
||||||
self.complete_forward_with_error(token, rw)
|
self.complete_forward_with_error(token)
|
||||||
|
|
||||||
def do_forward_discard(self, token, addr, nbytes):
|
def do_forward_discard(self, token, addr, nbytes):
|
||||||
if self.data_only or self.should_forward_io(0, addr):
|
if self.data_only or self.should_forward_io(IoDir.WRITE, addr):
|
||||||
self.vol.do_forward_discard(token, addr, nbytes)
|
self.vol.do_forward_discard(token, addr, nbytes)
|
||||||
else:
|
else:
|
||||||
self.complete_forward_with_error(token, rw)
|
self.complete_forward_with_error(token)
|
||||||
|
|
||||||
def arm(self):
|
def arm(self):
|
||||||
self.armed = True
|
self.armed = True
|
||||||
@ -812,7 +785,7 @@ class TraceDevice(Volume):
|
|||||||
|
|
||||||
|
|
||||||
lib = OcfLib.getInstance()
|
lib = OcfLib.getInstance()
|
||||||
lib.ocf_io_get_priv.restype = POINTER(VolumeIoPriv)
|
lib.ocf_io_get_offset.restype = c_uint32
|
||||||
lib.ocf_io_get_volume.argtypes = [c_void_p]
|
lib.ocf_io_get_volume.argtypes = [c_void_p]
|
||||||
lib.ocf_io_get_volume.restype = c_void_p
|
lib.ocf_io_get_volume.restype = c_void_p
|
||||||
lib.ocf_io_get_data.argtypes = [c_void_p]
|
lib.ocf_io_get_data.argtypes = [c_void_p]
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
|
||||||
from ctypes import c_int, memmove, cast, c_void_p
|
from ctypes import memmove, cast, c_void_p, c_uint64
|
||||||
from enum import IntEnum
|
|
||||||
from itertools import product
|
|
||||||
import random
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -18,6 +15,7 @@ from pyocf.types.volume_core import CoreVolume
|
|||||||
from pyocf.types.data import Data
|
from pyocf.types.data import Data
|
||||||
from pyocf.types.io import IoDir, Sync
|
from pyocf.types.io import IoDir, Sync
|
||||||
from pyocf.utils import Size
|
from pyocf.utils import Size
|
||||||
|
from pyocf.ocf import OcfLib
|
||||||
|
|
||||||
|
|
||||||
def __io(io, data):
|
def __io(io, data):
|
||||||
@ -48,19 +46,19 @@ class FlagsValVolume(RamVolume):
|
|||||||
self.fail = False
|
self.fail = False
|
||||||
super().__init__(size)
|
super().__init__(size)
|
||||||
|
|
||||||
def set_check(self, check):
|
def set_check(self):
|
||||||
self.check = check
|
self.check = True
|
||||||
|
self.fail = True
|
||||||
|
|
||||||
def submit_io(self, io):
|
def do_forward_io(self, token, rw, addr, nbytes, offset):
|
||||||
if self.check:
|
if self.check:
|
||||||
flags = io.contents._flags
|
flags = lib.ocf_forward_get_flags(token)
|
||||||
if flags != self.flags:
|
if flags == self.flags:
|
||||||
self.fail = True
|
self.fail = False
|
||||||
super().submit_io(io)
|
super().do_forward_io(token, rw, addr, nbytes, offset)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("cache_mode", CacheMode)
|
def test_io_flags(pyocf_ctx):
|
||||||
def test_io_flags(pyocf_ctx, cache_mode):
|
|
||||||
"""
|
"""
|
||||||
Verify that I/O flags provided at the top volume interface
|
Verify that I/O flags provided at the top volume interface
|
||||||
are propagated down to bottom volumes for all associated
|
are propagated down to bottom volumes for all associated
|
||||||
@ -74,44 +72,54 @@ def test_io_flags(pyocf_ctx, cache_mode):
|
|||||||
|
|
||||||
pyocf_ctx.register_volume_type(FlagsValVolume)
|
pyocf_ctx.register_volume_type(FlagsValVolume)
|
||||||
|
|
||||||
cache_device = FlagsValVolume(Size.from_MiB(50), flags)
|
cache_device = FlagsValVolume(Size.from_MiB(50), 0)
|
||||||
core_device = FlagsValVolume(Size.from_MiB(50), flags)
|
core_device = FlagsValVolume(Size.from_MiB(50), flags)
|
||||||
|
|
||||||
cache = Cache.start_on_device(cache_device, cache_mode=cache_mode)
|
cache = Cache.start_on_device(cache_device, cache_mode=CacheMode.WB)
|
||||||
core = Core.using_device(core_device)
|
core = Core.using_device(core_device)
|
||||||
|
|
||||||
cache.add_core(core)
|
cache.add_core(core)
|
||||||
vol = CoreVolume(core)
|
vol = CoreVolume(core)
|
||||||
|
|
||||||
cache_device.set_check(True)
|
def set_check():
|
||||||
core_device.set_check(True)
|
cache_device.set_check()
|
||||||
|
core_device.set_check()
|
||||||
|
|
||||||
# write miss
|
# write miss
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.WRITE, flags)
|
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.WRITE, flags)
|
||||||
assert not cache_device.fail
|
assert not cache_device.fail
|
||||||
assert not core_device.fail
|
|
||||||
|
|
||||||
# read miss
|
# read miss
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.READ, flags)
|
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.READ, flags)
|
||||||
assert not cache_device.fail
|
|
||||||
assert not core_device.fail
|
assert not core_device.fail
|
||||||
|
|
||||||
# "dirty" read hit
|
# "dirty" read hit
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.READ, flags)
|
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.READ, flags)
|
||||||
assert not cache_device.fail
|
assert not cache_device.fail
|
||||||
assert not core_device.fail
|
|
||||||
|
|
||||||
# "clean" read hit
|
# "clean" read hit
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.READ, flags)
|
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.READ, flags)
|
||||||
assert not cache_device.fail
|
assert not cache_device.fail
|
||||||
assert not core_device.fail
|
|
||||||
|
cache.change_cache_mode(CacheMode.WT)
|
||||||
|
|
||||||
# "dirty" write hit
|
# "dirty" write hit
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.WRITE, flags)
|
io_to_exp_obj(vol, block_size * 0, block_size, data, 0, IoDir.WRITE, flags)
|
||||||
assert not cache_device.fail
|
assert not cache_device.fail
|
||||||
assert not core_device.fail
|
assert not core_device.fail
|
||||||
|
|
||||||
# "clean" write hit
|
# "clean" write hit
|
||||||
|
set_check()
|
||||||
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.WRITE, flags)
|
io_to_exp_obj(vol, block_size * 1, block_size, data, 0, IoDir.WRITE, flags)
|
||||||
assert not cache_device.fail
|
assert not cache_device.fail
|
||||||
assert not core_device.fail
|
assert not core_device.fail
|
||||||
|
|
||||||
|
|
||||||
|
lib = OcfLib.getInstance()
|
||||||
|
lib.ocf_forward_get_flags.argtypes = [c_uint64]
|
||||||
|
lib.ocf_forward_get_flags.restype = c_uint64
|
||||||
|
@ -12,7 +12,7 @@ from threading import Event
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from pyocf.ocf import OcfLib
|
from pyocf.ocf import OcfLib
|
||||||
from pyocf.types.volume import RamVolume, ErrorDevice, TraceDevice, IoFlags, VolumeIoPriv
|
from pyocf.types.volume import RamVolume, ErrorDevice, TraceDevice, IoFlags
|
||||||
from pyocf.types.cvolume import CVolume
|
from pyocf.types.cvolume import CVolume
|
||||||
from pyocf.types.data import Data
|
from pyocf.types.data import Data
|
||||||
from pyocf.types.io import IoDir
|
from pyocf.types.io import IoDir
|
||||||
@ -287,19 +287,25 @@ def test_io_propagation_basic(pyocf_ctx):
|
|||||||
ret = cvol_submit_data_io(cvol, addr, io_size)
|
ret = cvol_submit_data_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_flush_io(cvol, addr, io_size, IoFlags.FLUSH)
|
ret = cvol_submit_flush_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_discard_io(cvol, addr, io_size)
|
ret = cvol_submit_discard_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
for io_type in TraceDevice.IoType:
|
ios = io_trace[vol][TraceDevice.IoType.Data]
|
||||||
ios = io_trace[vol][io_type]
|
assert len(ios) == 1
|
||||||
assert len(ios) == 1
|
assert ios[0].dir == IoDir.WRITE
|
||||||
io = ios[0]
|
assert ios[0].addr == addr.B - int(vol_begin[i])
|
||||||
assert io.dir == IoDir.WRITE
|
assert ios[0].bytes == io_size.B
|
||||||
assert io.addr == addr.B - int(vol_begin[i])
|
|
||||||
assert io.bytes == io_size.B
|
ios = io_trace[vol][TraceDevice.IoType.Flush]
|
||||||
|
assert len(ios) == i + 1
|
||||||
|
|
||||||
|
ios = io_trace[vol][TraceDevice.IoType.Discard]
|
||||||
|
assert len(ios) == 1
|
||||||
|
assert ios[0].addr == addr.B - int(vol_begin[i])
|
||||||
|
assert ios[0].bytes == io_size.B
|
||||||
|
|
||||||
cvol.close()
|
cvol.close()
|
||||||
cvol.destroy()
|
cvol.destroy()
|
||||||
@ -355,27 +361,36 @@ def test_io_propagation_cross_boundary(pyocf_ctx):
|
|||||||
ret = cvol_submit_data_io(cvol, addr, io_size)
|
ret = cvol_submit_data_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_flush_io(cvol, addr, io_size, IoFlags.FLUSH)
|
ret = cvol_submit_flush_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_discard_io(cvol, addr, io_size)
|
ret = cvol_submit_discard_io(cvol, addr, io_size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
for io_type in TraceDevice.IoType:
|
ios1 = io_trace[vols[i]][TraceDevice.IoType.Data]
|
||||||
ios1 = io_trace[vols[i]][io_type]
|
ios2 = io_trace[vols[i + 1]][TraceDevice.IoType.Data]
|
||||||
ios2 = io_trace[vols[i + 1]][io_type]
|
assert len(ios1) == 1
|
||||||
|
assert ios1[0].dir == IoDir.WRITE
|
||||||
|
assert ios1[0].addr == int(vols[i].vol.size - (io_size / 2))
|
||||||
|
assert ios1[0].bytes == io_size.B / 2
|
||||||
|
assert len(ios2) == 1
|
||||||
|
assert ios2[0].dir == IoDir.WRITE
|
||||||
|
assert ios2[0].addr == 0
|
||||||
|
assert ios2[0].bytes == io_size.B / 2
|
||||||
|
|
||||||
assert len(ios1) == 1
|
ios1 = io_trace[vols[i]][TraceDevice.IoType.Flush]
|
||||||
io = ios1[0]
|
ios2 = io_trace[vols[i + 1]][TraceDevice.IoType.Flush]
|
||||||
assert io.dir == IoDir.WRITE
|
assert len(ios1) == 1
|
||||||
assert io.addr == int(vols[i].vol.size - (io_size / 2))
|
assert len(ios2) == 1
|
||||||
assert io.bytes == io_size.B / 2
|
|
||||||
|
|
||||||
assert len(ios2) == 1
|
ios1 = io_trace[vols[i]][TraceDevice.IoType.Discard]
|
||||||
io = ios2[0]
|
ios2 = io_trace[vols[i + 1]][TraceDevice.IoType.Discard]
|
||||||
assert io.dir == IoDir.WRITE
|
assert len(ios1) == 1
|
||||||
assert io.addr == 0
|
assert ios1[0].addr == int(vols[i].vol.size - (io_size / 2))
|
||||||
assert io.bytes == io_size.B / 2
|
assert ios1[0].bytes == io_size.B / 2
|
||||||
|
assert len(ios2) == 1
|
||||||
|
assert ios2[0].addr == 0
|
||||||
|
assert ios2[0].bytes == io_size.B / 2
|
||||||
|
|
||||||
cvol.close()
|
cvol.close()
|
||||||
cvol.destroy()
|
cvol.destroy()
|
||||||
@ -483,25 +498,51 @@ def test_io_propagation_multiple_subvolumes(pyocf_ctx, rand_seed):
|
|||||||
ret = cvol_submit_data_io(cvol, addr, size)
|
ret = cvol_submit_data_io(cvol, addr, size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_flush_io(cvol, addr, size, IoFlags.FLUSH)
|
ret = cvol_submit_flush_io(cvol, addr, size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
ret = cvol_submit_discard_io(cvol, addr, size)
|
ret = cvol_submit_discard_io(cvol, addr, size)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
|
|
||||||
for vol in middle:
|
for vol in middle:
|
||||||
for io in io_trace[vol].values():
|
ios = io_trace[vol][TraceDevice.IoType.Data]
|
||||||
assert len(io) == 1
|
assert len(ios) == 1
|
||||||
assert io[0].addr == 0
|
assert ios[0].addr == 0
|
||||||
assert io[0].bytes == int(vol.vol.size)
|
assert ios[0].bytes == int(vol.vol.size)
|
||||||
|
|
||||||
for io in io_trace[first].values():
|
ios = io_trace[first][TraceDevice.IoType.Data]
|
||||||
assert io[0].addr == int(start_offset)
|
assert len(ios) == 1
|
||||||
assert io[0].bytes == int(vol_size - start_offset)
|
assert ios[0].addr == int(start_offset)
|
||||||
|
assert ios[0].bytes == int(vol_size - start_offset)
|
||||||
|
|
||||||
for io in io_trace[last].values():
|
ios = io_trace[last][TraceDevice.IoType.Data]
|
||||||
assert io[0].addr == 0
|
assert len(ios) == 1
|
||||||
assert io[0].bytes == int(end_offset)
|
assert ios[0].addr == 0
|
||||||
|
assert ios[0].bytes == int(end_offset)
|
||||||
|
|
||||||
|
ios = io_trace[vol][TraceDevice.IoType.Flush]
|
||||||
|
assert len(ios) == 1
|
||||||
|
|
||||||
|
ios = io_trace[first][TraceDevice.IoType.Flush]
|
||||||
|
assert len(ios) == 1
|
||||||
|
|
||||||
|
ios = io_trace[last][TraceDevice.IoType.Flush]
|
||||||
|
assert len(ios) == 1
|
||||||
|
|
||||||
|
ios = io_trace[vol][TraceDevice.IoType.Discard]
|
||||||
|
assert len(ios) == 1
|
||||||
|
assert ios[0].addr == 0
|
||||||
|
assert ios[0].bytes == int(vol.vol.size)
|
||||||
|
|
||||||
|
ios = io_trace[first][TraceDevice.IoType.Discard]
|
||||||
|
assert len(ios) == 1
|
||||||
|
assert ios[0].addr == int(start_offset)
|
||||||
|
assert ios[0].bytes == int(vol_size - start_offset)
|
||||||
|
|
||||||
|
ios = io_trace[last][TraceDevice.IoType.Discard]
|
||||||
|
assert len(ios) == 1
|
||||||
|
assert ios[0].addr == 0
|
||||||
|
assert ios[0].bytes == int(end_offset)
|
||||||
|
|
||||||
cvol.close()
|
cvol.close()
|
||||||
cvol.destroy()
|
cvol.destroy()
|
||||||
@ -538,16 +579,16 @@ def test_io_completion(pyocf_ctx, rand_seed):
|
|||||||
self.pending_ios = []
|
self.pending_ios = []
|
||||||
self.io_submitted = Event()
|
self.io_submitted = Event()
|
||||||
|
|
||||||
def do_submit_io(self, io):
|
def do_forward_io(self, token, rw, addr, nbytes, offset):
|
||||||
self.pending_ios.append(("io", io))
|
self.pending_ios.append(("io", token, rw, addr, nbytes, offset))
|
||||||
self.io_submitted.set()
|
self.io_submitted.set()
|
||||||
|
|
||||||
def do_submit_flush(self, flush):
|
def do_forward_flush(self, token):
|
||||||
self.pending_ios.append(("flush", flush))
|
self.pending_ios.append(("flush", token))
|
||||||
self.io_submitted.set()
|
self.io_submitted.set()
|
||||||
|
|
||||||
def do_submit_discard(self, discard):
|
def do_forward_discard(self, token, addr, nbytes):
|
||||||
self.pending_ios.append(("discard", discard))
|
self.pending_ios.append(("discard", token, addr, nbytes))
|
||||||
self.io_submitted.set()
|
self.io_submitted.set()
|
||||||
|
|
||||||
def wait_submitted(self):
|
def wait_submitted(self):
|
||||||
@ -558,13 +599,13 @@ def test_io_completion(pyocf_ctx, rand_seed):
|
|||||||
if not self.pending_ios:
|
if not self.pending_ios:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
io_type, io = self.pending_ios.pop()
|
io_type, token, *params = self.pending_ios.pop()
|
||||||
if io_type == "io":
|
if io_type == "io":
|
||||||
super().do_submit_io(io)
|
super().do_forward_io(token, *params)
|
||||||
elif io_type == "flush":
|
elif io_type == "flush":
|
||||||
super().do_submit_flush(io)
|
super().do_forward_flush(token)
|
||||||
elif io_type == "discard":
|
elif io_type == "discard":
|
||||||
super().do_submit_discard(io)
|
super().do_forward_discard(token, *params)
|
||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
@ -586,14 +627,18 @@ def test_io_completion(pyocf_ctx, rand_seed):
|
|||||||
addr = vol_size / 2
|
addr = vol_size / 2
|
||||||
size = (subvol_count - 1) * vol_size
|
size = (subvol_count - 1) * vol_size
|
||||||
|
|
||||||
for op, flags in [("submit", 0), ("submit_flush", IoFlags.FLUSH), ("submit_discard", 0)]:
|
for op, cnt in [
|
||||||
|
("submit", subvol_count),
|
||||||
|
("submit_flush", len(vols)),
|
||||||
|
("submit_discard", subvol_count)
|
||||||
|
]:
|
||||||
io = cvol.new_io(
|
io = cvol.new_io(
|
||||||
queue=None,
|
queue=None,
|
||||||
addr=addr,
|
addr=addr,
|
||||||
length=size,
|
length=size,
|
||||||
direction=IoDir.WRITE,
|
direction=IoDir.WRITE,
|
||||||
io_class=0,
|
io_class=0,
|
||||||
flags=flags,
|
flags=0,
|
||||||
)
|
)
|
||||||
completion = OcfCompletion([("err", c_int)])
|
completion = OcfCompletion([("err", c_int)])
|
||||||
io.callback = completion.callback
|
io.callback = completion.callback
|
||||||
@ -604,7 +649,7 @@ def test_io_completion(pyocf_ctx, rand_seed):
|
|||||||
submit_fn = getattr(io, op)
|
submit_fn = getattr(io, op)
|
||||||
submit_fn()
|
submit_fn()
|
||||||
|
|
||||||
pending_vols = vols[:subvol_count]
|
pending_vols = vols[:cnt]
|
||||||
for v in pending_vols:
|
for v in pending_vols:
|
||||||
v.wait_submitted()
|
v.wait_submitted()
|
||||||
|
|
||||||
@ -674,7 +719,7 @@ def test_io_error(pyocf_ctx, rand_seed):
|
|||||||
assert ret == -OcfErrorCode.OCF_ERR_IO
|
assert ret == -OcfErrorCode.OCF_ERR_IO
|
||||||
|
|
||||||
# verify flush properly propagated
|
# verify flush properly propagated
|
||||||
ret = cvol_submit_flush_io(cvol, addr, size, IoFlags.FLUSH)
|
ret = cvol_submit_flush_io(cvol, addr, size)
|
||||||
assert ret == -OcfErrorCode.OCF_ERR_IO
|
assert ret == -OcfErrorCode.OCF_ERR_IO
|
||||||
|
|
||||||
# verdiscard discard properly propagated
|
# verdiscard discard properly propagated
|
||||||
|
Loading…
Reference in New Issue
Block a user