Skip to content

Commit 5808059

Browse files
author
Kamil Gierszewski
committed
test: add test_alru_change_trigger_dirty_ratio_during_io test
Signed-off-by: Kamil Gierszewski <kamil.gierszewski@huawei.com>
1 parent b0b861d commit 5808059

File tree

1 file changed

+125
-2
lines changed

1 file changed

+125
-2
lines changed

test/functional/tests/cache_ops/test_cleaning_policy_operation.py

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,24 @@
44
# SPDX-License-Identifier: BSD-3-Clause
55
#
66

7+
import random
78
import time
89
import pytest
910

11+
from datetime import timedelta
12+
1013
from api.cas import casadm
1114
from api.cas.cache_config import (
1215
CacheMode,
1316
CleaningPolicy,
1417
FlushParametersAcp,
1518
FlushParametersAlru,
1619
Time,
20+
SeqCutOffPolicy,
1721
)
1822
from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan
1923
from core.test_run import TestRun
24+
from test_tools.iostat import IOstatBasic
2025
from type_def.size import Size, Unit
2126
from test_tools.udev import Udev
2227
from test_tools.fio.fio import Fio
@@ -106,7 +111,7 @@ def test_cleaning_policies_in_write_back(cleaning_policy: CleaningPolicy):
106111
@pytest.mark.parametrize("cleaning_policy", CleaningPolicy)
107112
@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
108113
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
109-
def test_cleaning_policies_in_write_through(cleaning_policy):
114+
def test_cleaning_policies_in_write_through(cleaning_policy: CleaningPolicy):
110115
"""
111116
title: Test for cleaning policy operation in Write-Through cache mode.
112117
description: |
@@ -257,7 +262,7 @@ def check_cleaning_policy_operation(
257262
case CleaningPolicy.nop:
258263
if (
259264
core_writes_after_wait_for_cleaning != Size.zero()
260-
or core_writes_before_wait_for_cleaning != Size.zero()
265+
or core_writes_before_wait_for_cleaning != Size.zero()
261266
):
262267
TestRun.LOGGER.error(
263268
"NOP cleaning policy is not working properly! "
@@ -275,3 +280,121 @@ def check_cleaning_policy_operation(
275280
"ACP cleaning policy is not working properly! "
276281
"Core writes should increase in time while cleaning dirty data"
277282
)
283+
284+
285+
@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
286+
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
287+
def test_alru_change_trigger_dirty_ratio_during_io():
288+
"""
289+
title: Test ALRU with trigger dirty ratio param during I/O
290+
description: |
291+
Verify that ALRU is able to start cleaning to expected dirty ratio under constant I/O.
292+
pass_criteria:
293+
- Dirty cache lines are being cleaned after trigger dirty ratio change during I/O.
294+
- Dirty cache lines are cleaned to expected dirty ratio after stopping I/O
295+
"""
296+
iterations = 10
297+
298+
with TestRun.step("Prepare cache and core devices"):
299+
cache_dev = TestRun.disks["cache"]
300+
core_dev = TestRun.disks["core"]
301+
302+
cache_size = Size(1, Unit.GiB)
303+
cache_dev.create_partitions([cache_size])
304+
core_dev.create_partitions([Size(2, Unit.GiB)])
305+
306+
with TestRun.step(f"Disable udev"):
307+
Udev.disable()
308+
309+
with TestRun.step("Start cache"):
310+
cache = casadm.start_cache(cache_dev.partitions[0], force=True, cache_mode=CacheMode.WB)
311+
312+
with TestRun.step("Add core"):
313+
core = cache.add_core(core_dev.partitions[0])
314+
315+
with TestRun.step("Set params for ALRU cleaning policy"):
316+
params = FlushParametersAlru.default_alru_params()
317+
params.wake_up_time = Time(seconds=1)
318+
params.staleness_time = Time(seconds=3600)
319+
cache.set_params_alru(alru_params=params)
320+
321+
with TestRun.step("Disable sequential cut-off and set cleaning to ALRU"):
322+
cache.set_seq_cutoff_policy(SeqCutOffPolicy.never)
323+
cache.set_cleaning_policy(CleaningPolicy.alru)
324+
325+
for _ in TestRun.iteration(
326+
range(0, iterations),
327+
"Start changing trigger dirty ratio param during I/O and check if flush occurred",
328+
):
329+
330+
params = FlushParametersAlru.default_alru_params()
331+
332+
fio = (
333+
Fio()
334+
.create_command()
335+
.io_engine(IoEngine.libaio)
336+
.block_size(Size(4, Unit.KiB))
337+
.target(core)
338+
.direct()
339+
.time_based()
340+
.run_time(timedelta(minutes=10))
341+
.read_write(ReadWrite.randwrite)
342+
)
343+
344+
dirty_ratio_test_threshold = random.randint(0, 100)
345+
346+
with TestRun.step("Disable cache cleaning"):
347+
cache.set_seq_cutoff_policy(SeqCutOffPolicy.never)
348+
349+
with TestRun.step("Start running I/O to exported object in background"):
350+
fio_pid = fio.run_in_background()
351+
352+
with TestRun.step("Wait until dirty data on cache exceed dirty ratio threshold"):
353+
354+
while TestRun.executor.check_if_process_exists(fio_pid):
355+
dirty_blocks_percentage_on_cache = cache.get_statistics(
356+
percentage_val=True
357+
).usage_stats.dirty
358+
359+
if dirty_blocks_percentage_on_cache >= dirty_ratio_test_threshold:
360+
break
361+
time.sleep(5)
362+
363+
with TestRun.step("Set cache cleaning policy to alru"):
364+
params.trigger_dirty_ratio = dirty_ratio_test_threshold
365+
cache.set_params_alru(alru_params=params)
366+
367+
with TestRun.step("Check if cleaning started after changing cleaning policy"):
368+
time.sleep(5)
369+
370+
iostat_core = IOstatBasic.get_iostat_list([core_dev.get_device_id()])
371+
core_writes = iostat_core[0].total_writes
372+
373+
if core_writes == Size.zero():
374+
TestRun.fail(f"Cleaning on cache haven`t started")
375+
376+
with TestRun.step("Stop I/O to exported object"):
377+
TestRun.executor.kill_process(fio_pid)
378+
379+
with TestRun.step("Check if cache has been cleaned to set threshold after stopping I/O"):
380+
max_cleaning_time = timedelta(seconds=60)
381+
t_end = time.time() + max_cleaning_time.seconds
382+
383+
while time.time() < t_end:
384+
dirty_blocks_on_cache_before = cache.get_statistics(
385+
percentage_val=True).usage_stats.dirty
386+
time.sleep(20)
387+
dirty_blocks_on_cache_after = cache.get_statistics(
388+
percentage_val=True).usage_stats.dirty
389+
if dirty_blocks_on_cache_before == dirty_blocks_on_cache_after:
390+
break
391+
392+
dirty_blocks_cache_percentage = cache.get_statistics(
393+
percentage_val=True
394+
).usage_stats.dirty
395+
396+
if not dirty_ratio_test_threshold == dirty_blocks_cache_percentage:
397+
TestRun.fail("Dirty block percentage outside of defined range")
398+
399+
with TestRun.step("Purge cache"):
400+
casadm.purge_cache(cache_id=cache.cache_id)

0 commit comments

Comments
 (0)