Skip to content

Commit 70d6ca5

Browse files
tests: ALRU: don't clean if dirty < threshold
Co-authored-by: aider (gpt-5) <aider@aider.chat> Signed-off-by: Michal Mielewczyk <michal.mielewczyk@huawei.com>
1 parent 9c5912e commit 70d6ca5

File tree

1 file changed

+96
-3
lines changed
  • test/functional/tests/lazy_writes/cleaning_policy

1 file changed

+96
-3
lines changed

test/functional/tests/lazy_writes/cleaning_policy/test_alru.py

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#
22
# Copyright(c) 2020-2021 Intel Corporation
3-
# Copyright(c) 2024 Huawei Technologies Co., Ltd.
3+
# Copyright(c) 2024-2025 Huawei Technologies Co., Ltd.
44
# SPDX-License-Identifier: BSD-3-Clause
55
#
66

@@ -10,12 +10,18 @@
1010
from datetime import timedelta
1111

1212
from api.cas import casadm
13-
from api.cas.cache_config import CacheMode, CleaningPolicy, FlushParametersAlru, SeqCutOffPolicy
13+
from api.cas.cache_config import (
14+
CacheMode,
15+
CleaningPolicy,
16+
FlushParametersAlru,
17+
SeqCutOffPolicy,
18+
CacheLineSize,
19+
)
1420
from core.test_run import TestRun
1521
from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan
1622
from test_tools.fio.fio import Fio
1723
from test_tools.fio.fio_param import ReadWrite, IoEngine
18-
from test_tools.os_tools import kill_all_io
24+
from test_tools.os_tools import kill_all_io, sync
1925
from test_tools.udev import Udev
2026
from type_def.size import Size, Unit
2127
from type_def.time import Time
@@ -118,3 +124,90 @@ def prepare():
118124
)
119125

120126
return cache, core
127+
128+
129+
@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
130+
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
131+
@pytest.mark.parametrize("inertia", [Size.zero(), Size(1500, Unit.MiB)])
132+
@pytest.mark.parametrizex(
133+
"cache_line_size",
134+
[CacheLineSize.LINE_4KiB, CacheLineSize.LINE_64KiB],
135+
)
136+
def test_alru_dirty_ratio_inertia_no_cleaning_if_dirty_below_threshold(cache_line_size, inertia):
137+
"""
138+
title: Test ALRU dirty ratio inertia — no cleaning below threshold
139+
description: |
140+
Verify that ALRU cleaning is not triggered when the number of dirty cache lines is lower than
141+
(threshold - intertia)
142+
pass_criteria:
143+
- The cleaning is not triggered when dirty data doesn't exceed the specified threshold.
144+
"""
145+
with TestRun.step("Prepare disks for cache and core"):
146+
cache_dev = TestRun.disks["cache"]
147+
core_dev = TestRun.disks["core"]
148+
149+
cache_dev.create_partitions([Size(3, Unit.GiB)])
150+
core_dev.create_partitions([Size(10, Unit.GiB)])
151+
152+
with TestRun.step("Disable udev"):
153+
Udev.disable()
154+
155+
with TestRun.step("Start cache and add core"):
156+
cache = casadm.start_cache(
157+
cache_dev.partitions[0],
158+
cache_line_size=cache_line_size,
159+
force=True,
160+
cache_mode=CacheMode.WB,
161+
)
162+
core = cache.add_core(core_dev.partitions[0])
163+
164+
with TestRun.step("Set ALRU and disable sequential cutoff"):
165+
cache.set_seq_cutoff_policy(SeqCutOffPolicy.never)
166+
cache.set_cleaning_policy(CleaningPolicy.alru)
167+
168+
with TestRun.step(f"Set alru params"):
169+
cache.set_params_alru(
170+
FlushParametersAlru(
171+
staleness_time=Time(seconds=3600),
172+
wake_up_time=Time(seconds=1),
173+
activity_threshold=Time(milliseconds=1000),
174+
dirty_ratio_threshold=90,
175+
dirty_ratio_inertia=inertia,
176+
)
177+
)
178+
179+
with TestRun.step("Run write workload to reach ~2GiB (≈66% of 3GiB) dirty data"):
180+
(
181+
Fio()
182+
.create_command()
183+
.io_engine(IoEngine.libaio)
184+
.size(cache.size * 0.66)
185+
.block_size(Size(4, Unit.KiB))
186+
.target(core)
187+
.direct()
188+
.read_write(ReadWrite.randwrite)
189+
.run()
190+
)
191+
192+
with TestRun.step("Make sure that the all IO has been completed"):
193+
sync()
194+
195+
with TestRun.step("Capture baseline dirty usage after I/O settles"):
196+
time.sleep(2)
197+
dirty_before_pct = cache.get_statistics(percentage_val=True).usage_stats.dirty
198+
dirty_before = cache.get_statistics().usage_stats.dirty
199+
if dirty_before_pct <= 60:
200+
TestRun.fail(
201+
f"Exception: Precondition not met: dirty cache lines must exceed 60% after I/O settles "
202+
f"(dirty={dirty_before}, dirty%={dirty_before_pct}%). Aborting test."
203+
)
204+
205+
with TestRun.step("Idle and verify dirty cache lines do not change and remain below threshold"):
206+
time.sleep(30)
207+
dirty_after = cache.get_statistics().usage_stats.dirty
208+
209+
if dirty_before > dirty_after:
210+
TestRun.fail(
211+
f"No flushing shall occur when dirty < threshold (dirty before={dirty_before}, "
212+
f"dirty after={dirty_after}, threshold={dirty_ratio_threshold}%)"
213+
)

0 commit comments

Comments
 (0)