def test_ioclass_stats_sum(random_cls): """ title: Test for sum of IO class statistics. description: | Check if statistics for configured IO classes sum up to cache/core statistics. pass_criteria: - Per class cache IO class statistics sum up to cache statistics. - Per class core IO class statistics sum up to core statistics. """ min_ioclass_id = 1 max_ioclass_id = 11 file_size_base = Unit.Blocks4096.value with TestRun.step("Test prepare"): caches, cores = prepare(random_cls) cache, core = caches[0], cores[0] with TestRun.step("Prepare IO class config file"): ioclass_list = [] for class_id in range(min_ioclass_id, max_ioclass_id): ioclass_list.append( IoClass(class_id=class_id, rule=f"file_size:le:{file_size_base * class_id}&done", priority=22)) IoClass.save_list_to_config_file(ioclass_list, True) with TestRun.step("Load IO class config file"): cache.load_io_class(ioclass_config.default_config_file_path) with TestRun.step( "Generate files with particular sizes in temporary folder"): files_list = [] for class_id in range(min_ioclass_id, max_ioclass_id): path = f"/tmp/test_file_{file_size_base * class_id}" File.create_file(path) f = File(path) f.padding(Size(file_size_base * class_id, Unit.Byte)) files_list.append(f) with TestRun.step("Copy files to mounted core"): core.mount(mountpoint) for f in files_list: TestRun.LOGGER.info(f"Copying file {f.name} to mounted core") f.copy(mountpoint) sync() # To prevent stats pollution by filesystem requests, umount core device # after files are copied core.unmount() sync() with TestRun.step( "Check if per class cache IO class statistics sum up to cache statistics" ): # Name of stats, which should not be compared not_compare_stats = ["clean", "occupancy", "free"] ioclass_id_list = list(range(min_ioclass_id, max_ioclass_id)) # Append default IO class id ioclass_id_list.append(0) cache_stats = cache.get_statistics_flat( stat_filter=[StatsFilter.usage, StatsFilter.req, StatsFilter.blk]) for ioclass_id in ioclass_id_list: ioclass_stats = cache.get_statistics_flat( stat_filter=[ StatsFilter.usage, StatsFilter.req, StatsFilter.blk ], io_class_id=ioclass_id, ) for stat_name in cache_stats: if stat_name in not_compare_stats: continue cache_stats[stat_name] -= ioclass_stats[stat_name] for stat_name in cache_stats: if stat_name in not_compare_stats: continue stat_val = (cache_stats[stat_name].get_value() if isinstance( cache_stats[stat_name], Size) else cache_stats[stat_name]) if stat_val != 0: TestRun.LOGGER.error(f"{stat_name} diverged for cache!\n") with TestRun.step( "Check if per class core IO class statistics sum up to core statistics" ): core_stats = core.get_statistics_flat( stat_filter=[StatsFilter.usage, StatsFilter.req, StatsFilter.blk]) for ioclass_id in ioclass_id_list: ioclass_stats = core.get_statistics_flat( stat_filter=[ StatsFilter.usage, StatsFilter.req, StatsFilter.blk ], io_class_id=ioclass_id, ) for stat_name in core_stats: if stat_name in not_compare_stats: continue core_stats[stat_name] -= ioclass_stats[stat_name] for stat_name in core_stats: if stat_name in not_compare_stats: continue stat_val = (core_stats[stat_name].get_value() if isinstance( core_stats[stat_name], Size) else core_stats[stat_name]) if stat_val != 0: TestRun.LOGGER.error(f"{stat_name} diverged for core!\n") with TestRun.step("Test cleanup"): for f in files_list: f.remove()
def test_ioclass_stats_sum(prepare_and_cleanup): """Check if stats for all set ioclasses sum up to cache stats""" cache, core = prepare() min_ioclass_id = 1 max_ioclass_id = 11 file_size_base = Unit.KibiByte.value * 4 TestProperties.LOGGER.info("Preparing ioclass config file") ioclass_config.create_ioclass_config( add_default_rule=True, ioclass_config_path=ioclass_config_path ) for i in range(min_ioclass_id, max_ioclass_id): ioclass_config.add_ioclass( ioclass_id=i, eviction_priority=22, allocation=True, rule=f"file_size:le:{file_size_base*i}&done", ioclass_config_path=ioclass_config_path, ) cache.load_io_class(ioclass_config_path) TestProperties.LOGGER.info("Generating files with particular sizes") files_list = [] for i in range(min_ioclass_id, max_ioclass_id): path = f"/tmp/test_file_{file_size_base*i}" File.create_file(path) f = File(path) f.padding(Size(file_size_base * i, Unit.Byte)) files_list.append(f) core.create_filesystem(Filesystem.ext4) cache.reset_counters() # Name of stats, which should not be compared not_compare_stats = ["clean", "occupancy"] ioclass_id_list = list(range(min_ioclass_id, max_ioclass_id)) # Append default ioclass id ioclass_id_list.append(0) TestProperties.LOGGER.info("Copying files to mounted core and stats check") for f in files_list: # To prevent stats pollution by filesystem requests, umount core device # after file is copied core.mount(mountpoint) f.copy(mountpoint) sync() core.unmount() sync() cache_stats = cache.get_cache_statistics( stat_filter=[StatsFilter.usage, StatsFilter.req, StatsFilter.blk] ) for ioclass_id in ioclass_id_list: ioclass_stats = cache.get_cache_statistics( stat_filter=[StatsFilter.usage, StatsFilter.req, StatsFilter.blk], io_class_id=ioclass_id, ) for stat_name in cache_stats: if stat_name in not_compare_stats: continue cache_stats[stat_name] -= ioclass_stats[stat_name] for stat_name in cache_stats: if stat_name in not_compare_stats: continue stat_val = ( cache_stats[stat_name].get_value() if isinstance(cache_stats[stat_name], Size) else cache_stats[stat_name] ) assert stat_val == 0, f"{stat_name} diverged!\n" # Test cleanup for f in files_list: f.remove()