Пример #1
0
from test_tools.disk_utils import Filesystem
from test_utils.output import CmdException
from test_utils.size import Size, Unit
from tests.lazy_writes.recovery.recovery_tests_methods import create_test_files, copy_file, \
    compare_files

test_file_size = Size(0.5, Unit.GibiByte)
mount_point = "/mnt"
test_file_path = os.path.join(mount_point, "test_file")


@pytest.mark.require_disk("cache",
                          DiskTypeSet([DiskType.optane, DiskType.nand]))
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
@pytest.mark.parametrizex("cache_mode",
                          CacheMode.with_traits(CacheModeTrait.LazyWrites))
@pytest.mark.parametrizex("cls",
                          [CacheLineSize.LINE_4KiB, CacheLineSize.LINE_64KiB])
@pytest.mark.parametrizex("filesystem", Filesystem)
@pytest.mark.parametrizex("direct", [True, False])
@pytest.mark.require_plugin("power_control")
def test_recovery_unplug_cache_fs(cache_mode, cls, filesystem, direct):
    """
            title: Test for recovery after cache drive removal - test with filesystem.
            description: |
              Verify that unflushed data can be safely recovered after, when SSD drive is removed
              after write completion - test with filesystem.
            pass_criteria:
              - CAS recovers successfully after cache drive unplug
              - No data corruption
    """
Пример #2
0
from storage_devices.device import Device
from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan
from core.test_run import TestRun
from test_tools.dd import Dd
from test_tools.disk_utils import Filesystem
from test_tools.fs_utils import create_random_test_file, remove
from test_tools.iostat import IOstatBasic
from test_utils.filesystem.file import File
from test_utils.os_utils import Udev, sync
from test_utils.size import Size, Unit

bs = Size(512, Unit.KibiByte)
mnt_point = "/mnt/cas/"


@pytest.mark.parametrizex("cache_mode", CacheMode.with_traits(CacheModeTrait.LazyWrites))
@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand]))
@pytest.mark.require_disk("core", DiskTypeLowerThan("cache"))
def test_clean_stop_cache(cache_mode):
    """
        title: Test of the ability to stop cache in modes with lazy writes.
        description: |
          Test if OpenCAS stops cache in modes with lazy writes without data loss.
        pass_criteria:
          - Cache stopping works properly.
          - Writes to exported object and core device during OpenCAS's work are equal
          - Data on core device is correct after cache is stopped.
    """
    with TestRun.step("Prepare devices for cache and core."):
        cache_dev = TestRun.disks['cache']
        cache_dev.create_partitions([Size(256, Unit.MebiByte)])
Пример #3
0
                    f"Discard request issued with wrong bytes count: {req.byte_count}, "
                    f"expected: {non_meta_size} bytes")

        cas_fio.read_write(ReadWrite.read)
        non_cas_fio.read_write(ReadWrite.read)
        cas_fio.verification_with_pattern("0x00")
        cas_fio.offset(metadata_size)
        cas_fio.run()
        non_cas_fio.run()

    with TestRun.step("Stopping cache"):
        cache.stop()


@pytest.mark.parametrizex("cache_mode",
                          CacheMode.with_traits(CacheModeTrait.InsertWrite))
@pytest.mark.parametrizex("filesystem", Filesystem)
@pytest.mark.parametrizex("cleaning_policy", CleaningPolicy)
@pytest.mark.parametrizex("trim_support_cache_core", [(False, True),
                                                      (True, False),
                                                      (True, True)])
@pytest.mark.require_disk("ssd1", DiskTypeSet([DiskType.optane,
                                               DiskType.nand]))
@pytest.mark.require_disk("ssd2", DiskTypeSet([DiskType.optane,
                                               DiskType.nand]))
@pytest.mark.require_disk("hdd", DiskTypeSet([DiskType.hdd, DiskType.hdd4k]))
def test_trim_device_discard_support(trim_support_cache_core, cache_mode,
                                     filesystem, cleaning_policy):
    """
        title: Trim requests supported on various cache and core devices.
        description: |
Пример #4
0
            if req.byte_count != non_meta_size:
                TestRun.fail(f"Discard request issued with wrong bytes count: {req.byte_count}, "
                             f"expected: {non_meta_size} bytes")

        cas_fio.read_write(ReadWrite.read)
        non_cas_fio.read_write(ReadWrite.read)
        cas_fio.verification_with_pattern("0x00")
        cas_fio.offset(metadata_size)
        cas_fio.run()
        non_cas_fio.run()

    with TestRun.step("Stopping cache"):
        cache.stop()


@pytest.mark.parametrizex("cache_mode", CacheMode.with_traits(CacheModeTrait.InsertWrite))
@pytest.mark.parametrizex("filesystem", Filesystem)
@pytest.mark.parametrizex("cleaning_policy", CleaningPolicy)
@pytest.mark.parametrizex("trim_support_cache_core", [(False, True), (True, False), (True, True)])
@pytest.mark.require_disk("ssd1", DiskTypeSet([DiskType.optane, DiskType.nand]))
@pytest.mark.require_disk("ssd2", DiskTypeSet([DiskType.optane, DiskType.nand]))
def test_trim_device_discard_support(
        trim_support_cache_core, cache_mode, filesystem, cleaning_policy):
    """
        title: Trim requests supported on various cache and core devices.
        description: |
          Handling trim requests support when various combination of SSD and HDD are used as
          cache and core.
        pass_criteria:
          - No system crash.
          - Discards detected on CAS.
def validate_block_stats(stats, stats_perc, cache_mode, fail_message):
    fail_message += f"in 'block' stats"
    if stats.block_stats.core.reads.value != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Core reads' is "
            f"{stats.block_stats.core.reads.value}, "
            f"should equal 0\n")
    if stats_perc.block_stats.core.reads != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Core reads' percentage is "
            f"{stats_perc.block_stats.core.reads}, "
            f"should equal 0\n")
    if stats.block_stats.cache.reads.value != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Cache reads' is "
            f"{stats.block_stats.cache.reads.value}, "
            f"should equal 0\n")
    if stats_perc.block_stats.cache.reads != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Cache reads' percentage is "
            f"{stats_perc.block_stats.cache.reads}, "
            f"should equal 0\n")
    if stats.block_stats.exp_obj.reads.value != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object reads' is "
            f"{stats.block_stats.exp_obj.reads.value}, "
            f"should equal 0\n")
    if stats_perc.block_stats.exp_obj.reads != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object reads' percentage is "
            f"{stats_perc.block_stats.exp_obj.reads}, "
            f"should equal 0\n")
    if stats.block_stats.exp_obj.writes.value != io_size.value:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object writes' is "
            f"{stats.block_stats.exp_obj.writes.value}, "
            f"should equal IO size: {io_size.value}\n")
    if stats_perc.block_stats.exp_obj.writes != 100:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object writes' percentage is "
            f"{stats_perc.block_stats.exp_obj.writes}, "
            f"should equal 100\n")
    if stats.block_stats.exp_obj.total.value != io_size.value:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object total' is "
            f"{stats.block_stats.exp_obj.total.value}, "
            f"should equal IO size: {io_size.value}\n")
    if stats_perc.block_stats.exp_obj.total != 100:
        TestRun.LOGGER.error(
            f"{fail_message} 'Exported object total' percentage is "
            f"{stats_perc.block_stats.exp_obj.total}, "
            f"should equal 100\n")
    if cache_mode not in CacheMode.with_traits(CacheModeTrait.InsertWrite):
        if stats.block_stats.core.writes.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' is "
                f"{stats.block_stats.core.writes.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.core.writes != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' percentage is "
                f"{stats_perc.block_stats.core.writes}, "
                f"should equal 100\n")
        if stats.block_stats.core.total.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' is "
                f"{stats.block_stats.core.total.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.core.total != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' percentage is "
                f"{stats_perc.block_stats.core.total}, "
                f"should equal 100\n")
        if stats.block_stats.cache.writes.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' is "
                f"{stats.block_stats.cache.writes.value}, "
                f"should equal 0\n")
        if stats_perc.block_stats.cache.writes != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' percentage is "
                f"{stats_perc.block_stats.cache.writes}, "
                f"should equal 0\n")
        if stats.block_stats.cache.total.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' is "
                f"{stats.block_stats.cache.total.value}, "
                f"should equal 0\n")
        if stats_perc.block_stats.cache.total != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' percentage is "
                f"{stats_perc.block_stats.cache.total}, "
                f"should equal 0\n")
    elif cache_mode in CacheMode.with_traits(
        CacheModeTrait.InsertWrite | CacheModeTrait.LazyWrites
    ):
        if stats.block_stats.core.writes.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' is "
                f"{stats.block_stats.core.writes.value}, "
                f"should equal 0\n")
        if stats_perc.block_stats.core.writes != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' percentage is "
                f"{stats_perc.block_stats.core.writes}, "
                f"should equal 0\n")
        if stats.block_stats.core.total.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' is "
                f"{stats.block_stats.core.total.value}, "
                f"should equal 0\n")
        if stats_perc.block_stats.core.total != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' percentage is "
                f"{stats_perc.block_stats.core.total}, "
                f"should equal 0\n")
        if stats.block_stats.cache.writes.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' is "
                f"{stats.block_stats.cache.writes.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.cache.writes != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' percentage is "
                f"{stats_perc.block_stats.cache.writes}, "
                f"should equal 100\n")
        if stats.block_stats.cache.total.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' is "
                f"{stats.block_stats.cache.total.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.cache.total != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' percentage is "
                f"{stats_perc.block_stats.cache.total}, "
                f"should equal 100\n")
    elif (
        cache_mode in CacheMode.with_traits(CacheModeTrait.InsertWrite)
        and cache_mode not in CacheMode.with_traits(CacheModeTrait.LazyWrites)
    ):
        if stats.block_stats.core.writes.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' is "
                f"{stats.block_stats.core.writes.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.core.writes != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core writes' percentage is "
                f"{stats_perc.block_stats.core.writes}, "
                f"should equal 100\n")
        if stats.block_stats.core.total.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' is "
                f"{stats.block_stats.core.total.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.core.total != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Core total' percentage is "
                f"{stats_perc.block_stats.core.total}, "
                f"should equal 100\n")
        if stats.block_stats.cache.writes.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' is "
                f"{stats.block_stats.cache.writes.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.cache.writes != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache writes' percentage is "
                f"{stats_perc.block_stats.cache.writes}, "
                f"should equal 100\n")
        if stats.block_stats.cache.total.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' is "
                f"{stats.block_stats.cache.total.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.block_stats.cache.total != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Cache total' percentage is "
                f"{stats_perc.block_stats.cache.total}, "
                f"should equal 100\n")
def validate_request_stats(stats, stats_perc, cache_mode, fail_message):
    fail_message += f"in 'request' stats"
    if stats.request_stats.read.hits != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read hits' is "
            f"{stats.request_stats.read.hits}, "
            f"should equal 0\n")
    if stats_perc.request_stats.read.hits != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read hits' percentage is "
            f"{stats_perc.request_stats.read.hits}, "
            f"should equal 0\n")
    if stats.request_stats.read.part_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read partial misses' is "
            f"{stats.request_stats.read.part_misses}, "
            f"should equal 0\n")
    if stats_perc.request_stats.read.part_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read partial misses' percentage is "
            f"{stats_perc.request_stats.read.part_misses}, "
            f"should equal 0\n")
    if stats.request_stats.read.full_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read full misses' is "
            f"{stats.request_stats.read.full_misses}, "
            f"should equal 0\n")
    if stats_perc.request_stats.read.full_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read full misses' percentage is "
            f"{stats_perc.request_stats.read.full_misses}, "
            f"should equal 0\n")
    if stats.request_stats.read.total != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read total' is "
            f"{stats.request_stats.read.total}, "
            f"should equal 0\n")
    if stats_perc.request_stats.read.total != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Read total' percentage is "
            f"{stats_perc.request_stats.read.total}, "
            f"should equal 0\n")
    if stats.request_stats.write.hits != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Write hits' is "
            f"{stats.request_stats.write.hits}, "
            f"should equal 0\n")
    if stats_perc.request_stats.write.hits != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Write hits' percentage is "
            f"{stats_perc.request_stats.write.hits}, "
            f"should equal 0\n")
    if stats.request_stats.write.part_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Write partial misses' is "
            f"{stats.request_stats.write.part_misses}, "
            f"should equal 0\n")
    if stats_perc.request_stats.write.part_misses != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Write partial misses' percentage is "
            f"{stats_perc.request_stats.write.part_misses}, "
            f"should equal 0\n")
    if stats.request_stats.pass_through_reads != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Pass-through reads' is "
            f"{stats.request_stats.pass_through_reads}, "
            f"should equal 0\n")
    if stats_perc.request_stats.pass_through_reads != 0:
        TestRun.LOGGER.error(
            f"{fail_message} 'Pass-through reads' percentage is "
            f"{stats_perc.request_stats.pass_through_reads}, "
            f"should equal 0\n")
    if stats.request_stats.requests_total != io_value:
        TestRun.LOGGER.error(
            f"{fail_message} 'Total requests' is "
            f"{stats.request_stats.requests_total}, "
            f"should equal IO size value: {io_value}\n")
    if stats_perc.request_stats.requests_total != 100:
        TestRun.LOGGER.error(
            f"{fail_message} 'Total requests' percentage is "
            f"{stats_perc.request_stats.requests_total}, "
            f"should equal 100\n")
    if cache_mode in CacheMode.with_traits(CacheModeTrait.InsertWrite):
        if stats.request_stats.write.full_misses != io_value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write full misses' is "
                f"{stats.request_stats.write.full_misses}, "
                f"should equal IO size value: {io_value}\n")
        if stats_perc.request_stats.write.full_misses != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write full misses' percentage is "
                f"{stats_perc.request_stats.write.full_misses}, "
                f"should equal 100\n")
        if stats.request_stats.write.total != io_value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write total' is "
                f"{stats.request_stats.write.total}, "
                f"should equal IO size value: {io_value}\n")
        if stats_perc.request_stats.write.total != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write total' percentage is "
                f"{stats_perc.request_stats.write.total}, "
                f"should equal 100\n")
        if stats.request_stats.pass_through_writes != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Pass-through writes' is "
                f"{stats.request_stats.pass_through_writes}, "
                f"should equal 0\n")
        if stats_perc.request_stats.pass_through_writes != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Pass-through writes' percentage is "
                f"{stats_perc.request_stats.pass_through_writes}, "
                f"should equal 0\n")
        if stats.request_stats.requests_serviced != io_value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Serviced requests' is "
                f"{stats.request_stats.requests_serviced}, "
                f"should equal IO size value: {io_value}\n")
        if stats_perc.request_stats.requests_serviced != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Serviced requests' percentage is "
                f"{stats_perc.request_stats.requests_serviced}, "
                f"should equal 100\n")
    else:
        if stats.request_stats.write.full_misses != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write full misses' is "
                f"{stats.request_stats.write.full_misses}, "
                f"should equal 0\n")
        if stats_perc.request_stats.write.full_misses != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write full misses' percentage is "
                f"{stats_perc.request_stats.write.full_misses}, "
                f"should equal 0\n")
        if stats.request_stats.write.total != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write total' is "
                f"{stats.request_stats.write.total}, "
                f"should equal 0\n")
        if stats_perc.request_stats.write.total != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Write total' percentage is "
                f"{stats_perc.request_stats.write.total}, "
                f"should equal 0\n")
        if stats.request_stats.pass_through_writes != io_value:
            TestRun.LOGGER.error(
                f"{fail_message} 'Pass-through writes' is "
                f"{stats.request_stats.pass_through_writes}, "
                f"should equal IO size value: {io_value}\n")
        if stats_perc.request_stats.pass_through_writes != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'Pass-through writes' percentage is "
                f"{stats_perc.request_stats.pass_through_writes}, "
                f"should equal 100\n")
        if stats.request_stats.requests_serviced != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Serviced requests' is "
                f"{stats.request_stats.requests_serviced}, "
                f"should equal 0\n")
        if stats_perc.request_stats.requests_serviced != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'Serviced requests' percentage is "
                f"{stats_perc.request_stats.requests_serviced}, "
                f"should equal 0\n")
def validate_usage_stats(stats, stats_perc, cache, cache_mode, fail_message):
    fail_message += f"in 'usage' stats"
    if cache_mode not in CacheMode.with_traits(CacheModeTrait.InsertWrite):
        if stats.usage_stats.occupancy.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'occupancy' is "
                f"{stats.usage_stats.occupancy.value}, "
                f"should equal 0\n")
        if stats_perc.usage_stats.occupancy != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'occupancy' percentage is "
                f"{stats_perc.usage_stats.occupancy}, "
                f"should equal 0\n")
        if stats.usage_stats.free != cache.size:
            TestRun.LOGGER.error(
                f"{fail_message} 'free' is "
                f"{stats.usage_stats.free.value}, "
                f"should equal cache size: {cache.size.value}\n")
        if stats_perc.usage_stats.free != 100:
            TestRun.LOGGER.error(
                f"{fail_message} 'free' percentage is "
                f"{stats_perc.usage_stats.free}, "
                f"should equal 100\n")
        if stats.usage_stats.clean.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'clean' is "
                f"{stats.usage_stats.clean.value}, "
                f"should equal 0\n")
        if stats_perc.usage_stats.clean != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'clean' percentage is "
                f"{stats_perc.usage_stats.clean}, "
                f"should equal 0\n")
        if stats.usage_stats.dirty.value != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'dirty' is "
                f"{stats.usage_stats.dirty.value}, "
                f"should equal 0\n")
        if stats_perc.usage_stats.dirty != 0:
            TestRun.LOGGER.error(
                f"{fail_message} 'dirty' percentage is "
                f"{stats_perc.usage_stats.dirty}, "
                f"should equal 0\n")
    else:
        occupancy_perc = round(100 * io_size.value / cache.size.value, 1)
        free = cache.size.value - io_size.value * cores_per_cache
        free_perc = round(100 * (cache.size.value - io_size.value
                          * cores_per_cache) / cache.size.value, 1)
        if stats.usage_stats.occupancy.value != io_size.value:
            TestRun.LOGGER.error(
                f"{fail_message} 'occupancy' is "
                f"{stats.usage_stats.occupancy.value}, "
                f"should equal IO size: {io_size.value}\n")
        if stats_perc.usage_stats.occupancy != occupancy_perc:
            TestRun.LOGGER.error(
                f"{fail_message} 'occupancy' percentage is "
                f"{stats_perc.usage_stats.occupancy}, "
                f"should equal {occupancy_perc}\n")
        if stats.usage_stats.free.value != free:
            TestRun.LOGGER.error(
                f"{fail_message} 'free' is "
                f"{stats.usage_stats.free.value}, "
                f"should equal {free}\n")
        if stats_perc.usage_stats.free != free_perc:
            TestRun.LOGGER.error(
                f"{fail_message} 'free' percentage is "
                f"{stats_perc.usage_stats.free}, "
                f"should equal {free_perc}\n")
        if cache_mode not in CacheMode.with_traits(CacheModeTrait.LazyWrites):
            if stats.usage_stats.clean.value != io_size.value:
                TestRun.LOGGER.error(
                    f"{fail_message} 'clean' is "
                    f"{stats.usage_stats.clean.value}, "
                    f"should equal IO size: {io_size.value}\n")
            if stats_perc.usage_stats.clean != 100:
                TestRun.LOGGER.error(
                    f"{fail_message} 'clean' percentage is "
                    f"{stats_perc.usage_stats.clean}, "
                    f"should equal 100\n")
            if stats.usage_stats.dirty.value != 0:
                TestRun.LOGGER.error(
                    f"{fail_message} 'dirty' is "
                    f"{stats.usage_stats.dirty.value}, "
                    f"should equal 0\n")
            if stats_perc.usage_stats.dirty != 0:
                TestRun.LOGGER.error(
                    f"{fail_message} 'dirty' percentage is "
                    f"{stats_perc.usage_stats.dirty}, "
                    f"should equal 0\n")
        else:
            if stats.usage_stats.clean.value != 0:
                TestRun.LOGGER.error(
                    f"{fail_message} 'clean' is "
                    f"{stats.usage_stats.clean.value}, "
                    f"should equal 0\n")
            if stats_perc.usage_stats.clean != 0:
                TestRun.LOGGER.error(
                    f"{fail_message} 'clean' percentage is "
                    f"{stats_perc.usage_stats.clean}, "
                    f"should equal 0\n")
            if stats.usage_stats.dirty.value != io_size.value:
                TestRun.LOGGER.error(
                    f"{fail_message} 'dirty' is "
                    f"{stats.usage_stats.dirty.value}, "
                    f"should equal IO size: {io_size.value}\n")
            if stats_perc.usage_stats.dirty != 100:
                TestRun.LOGGER.error(
                    f"{fail_message} 'dirty' percentage is "
                    f"{stats_perc.usage_stats.dirty}, "
                    f"should equal 100\n")