pyocf: test_eviction fixup

Signed-off-by: Michal Rakowski <michal.rakowski@intel.com>
This commit is contained in:
Michal Rakowski 2020-04-15 23:50:11 +02:00
parent 67577fc1ef
commit 0f85a73669
2 changed files with 32 additions and 18 deletions

View File

@ -136,6 +136,10 @@ class Size:
def sectors(self):
return self.bytes // self._SECTOR_SIZE
@property
def blocks_4k(self):
return self.bytes // 4096
def __str__(self):
if self.bytes < self._KiB:
return "{} B".format(self.B)

View File

@ -21,53 +21,63 @@ logger = logging.getLogger(__name__)
@pytest.mark.parametrize("cls", CacheLineSize)
@pytest.mark.parametrize("mode", [CacheMode.WT, CacheMode.WB, CacheMode.WO])
@pytest.mark.xfail # TODO: remove when fixed
def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLineSize):
"""Test if eviction does not occur when IO greater than cache size is submitted.
"""
cache_device = Volume(Size.from_MiB(20)) # this gives about 1.375 MiB actual caching space
cache_device = Volume(Size.from_MiB(20))
core_device = Volume(Size.from_MiB(5))
cache = Cache.start_on_device(cache_device, cache_mode=mode,
cache_line_size=cls)
cache_size = cache.get_stats()['conf']['size']
core_exported = Core.using_device(core_device)
cache.add_core(core_exported)
cache.set_seq_cut_off_policy(SeqCutOffPolicy.NEVER)
valid_io_size = Size.from_KiB(512)
valid_io_size = Size.from_B(cache_size.B // 2)
test_data = Data(valid_io_size)
send_io(core_exported, test_data)
stats = core_exported.cache.get_stats()
first_block_sts = stats['block']
first_usage_sts = stats['usage']
pt_writes_first = stats['req']['wr_pt']
assert stats["usage"]["occupancy"]["value"] == (valid_io_size.B / Size.from_KiB(4).B),\
"Occupancy after first IO"
prev_writes_to_core = stats["block"]["core_volume_wr"]["value"]
# Anything below 5 MiB is a valid size (less than core device size)
# Writing over 1.375 MiB in this case should go directly to core and shouldn't trigger eviction
# Writing over cache size (to the offset above first io) in this case should go
# directly to core and shouldn't trigger eviction
io_size_bigger_than_cache = Size.from_MiB(2)
io_offset = valid_io_size
test_data = Data(io_size_bigger_than_cache)
send_io(core_exported, test_data)
send_io(core_exported, test_data, io_offset)
if mode is not CacheMode.WT:
# Flush first write
cache.flush()
stats = core_exported.cache.get_stats()
second_block_sts = stats['block']
second_usage_sts = stats['usage']
pt_writes_second = stats['req']['wr_pt']
# Writes from IO greater than cache size should go directly to core
# Writes to core should equal the following:
# Previous writes to core + size written + size cleaned (reads from cache)
assert stats["block"]["core_volume_wr"]["value"] == \
stats["block"]["cache_volume_rd"]["value"] + \
prev_writes_to_core + io_size_bigger_than_cache.B / Size.from_KiB(4).B, \
"Writes to core after second IO"
# Occupancy shouldn't change (no eviction)
assert stats["usage"]["occupancy"]["value"] == (valid_io_size.B / Size.from_KiB(4).B),\
"Occupancy after second IO"
# Second write shouldn't affect cache and should go directly to core.
# Cache occupancy shouldn't change
# Second IO should go in PT
assert first_usage_sts['occupancy'] == \
second_usage_sts['occupancy']
assert pt_writes_first['value'] == 0
assert pt_writes_second['value'] == 1
assert second_block_sts['cache_volume_wr']['value'] == valid_io_size.blocks_4k
assert second_block_sts['core_volume_wr']['value'] == valid_io_size.blocks_4k + \
io_size_bigger_than_cache.blocks_4k
def send_io(exported_obj: Core, data: Data):
def send_io(exported_obj: Core, data: Data, addr: int = 0):
io = exported_obj.new_io(
exported_obj.cache.get_default_queue(),
0, data.size, IoDir.WRITE, 0, 0
addr, data.size, IoDir.WRITE, 0, 0
)
io.set_data(data)