def new_cleaning_parameters_random_values(cleaning_policy): if cleaning_policy == CleaningPolicy.alru: alru_params_range = FlushParametersAlru().alru_params_range() wake_up_time_random_value = Time(seconds=random.randint( *alru_params_range.wake_up_time)) staleness_time_random_value = Time(seconds=random.randint( *alru_params_range.staleness_time)) flush_max_buffers_random_value = random.randint( *alru_params_range.flush_max_buffers) activity_threshold_random_value = Time(milliseconds=random.randint( *alru_params_range.activity_threshold)) cleaning_params = FlushParametersAlru() cleaning_params.wake_up_time = wake_up_time_random_value cleaning_params.staleness_time = staleness_time_random_value cleaning_params.flush_max_buffers = flush_max_buffers_random_value cleaning_params.activity_threshold = activity_threshold_random_value if cleaning_policy == CleaningPolicy.acp: acp_params_range = FlushParametersAcp().acp_params_range() wake_up_time_random_value = Time(milliseconds=random.randint( *acp_params_range.wake_up_time)) flush_max_buffers_random_value = random.randint( *acp_params_range.flush_max_buffers) cleaning_params = FlushParametersAcp() cleaning_params.wake_up_time = wake_up_time_random_value cleaning_params.flush_max_buffers = flush_max_buffers_random_value return cleaning_params
def set_cleaning_policy_and_params(cache, cleaning_policy): if cleaning_policy != CleaningPolicy.DEFAULT: cache.set_cleaning_policy(cleaning_policy) current_cleaning_policy = cache.get_cleaning_policy() if current_cleaning_policy != cleaning_policy: TestRun.LOGGER.error(f"Cleaning policy is {current_cleaning_policy}, " f"should be {cleaning_policy}") if cleaning_policy == CleaningPolicy.alru: alru_params = FlushParametersAlru() alru_params.wake_up_time = Time(seconds=10) alru_params.staleness_time = Time(seconds=2) alru_params.flush_max_buffers = 100 alru_params.activity_threshold = Time(milliseconds=1000) cache.set_params_alru(alru_params) current_alru_params = cache.get_flush_parameters_alru() if current_alru_params != alru_params: failed_params = "" if current_alru_params.wake_up_time != alru_params.wake_up_time: failed_params += ( f"Wake Up time is {current_alru_params.wake_up_time}, " f"should be {alru_params.wake_up_time}\n") if current_alru_params.staleness_time != alru_params.staleness_time: failed_params += ( f"Staleness Time is {current_alru_params.staleness_time}, " f"should be {alru_params.staleness_time}\n") if current_alru_params.flush_max_buffers != alru_params.flush_max_buffers: failed_params += ( f"Flush Max Buffers is {current_alru_params.flush_max_buffers}, " f"should be {alru_params.flush_max_buffers}\n") if current_alru_params.activity_threshold != alru_params.activity_threshold: failed_params += ( f"Activity Threshold is {current_alru_params.activity_threshold}, " f"should be {alru_params.activity_threshold}\n") TestRun.LOGGER.error( f"ALRU parameters did not switch properly:\n{failed_params}") if cleaning_policy == CleaningPolicy.acp: acp_params = FlushParametersAcp() acp_params.wake_up_time = Time(milliseconds=100) acp_params.flush_max_buffers = 64 cache.set_params_acp(acp_params) current_acp_params = cache.get_flush_parameters_acp() if current_acp_params != acp_params: failed_params = "" if current_acp_params.wake_up_time != acp_params.wake_up_time: failed_params += ( f"Wake Up time is {current_acp_params.wake_up_time}, " f"should be {acp_params.wake_up_time}\n") if current_acp_params.flush_max_buffers != acp_params.flush_max_buffers: failed_params += ( f"Flush Max Buffers is {current_acp_params.flush_max_buffers}, " f"should be {acp_params.flush_max_buffers}\n") TestRun.LOGGER.error( f"ACP parameters did not switch properly:\n{failed_params}")
def test_flush_signal_core(cache_mode): """ title: Test for FLUSH nad FUA signals sent to core device in modes with lazy writes. description: | Test if OpenCAS transmits FLUSH and FUA signals to core device in modes with lazy writes. pass_criteria: - FLUSH requests should be passed to core device. - FUA requests should be passed to core device. """ with TestRun.step( "Set mark in syslog to not read entries existing before the test." ): Logs._read_syslog(Logs.last_read_line) with TestRun.step("Prepare devices for cache and core."): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(2, Unit.GibiByte)]) cache_part = cache_dev.partitions[0] core_dev = TestRun.scsi_debug_devices[0] with TestRun.step( "Start cache and add SCSI device with xfs filesystem as core."): cache = casadm.start_cache(cache_part, cache_mode) core_dev.create_filesystem(Filesystem.xfs) core = cache.add_core(core_dev) with TestRun.step("Mount exported object."): if core.is_mounted(): core.unmount() core.mount(mount_point) with TestRun.step("Turn off cleaning policy."): cache.set_cleaning_policy(CleaningPolicy.nop) with TestRun.step("Create temporary file on exported object."): tmp_file = create_random_test_file(f"{mount_point}/tmp.file", Size(1, Unit.GibiByte)) os_utils.sync() with TestRun.step("Flush cache."): cache.flush_cache() os_utils.sync() with TestRun.step( f"Check {syslog_path} for flush request and delete temporary file." ): Logs.check_syslog_for_signals() tmp_file.remove(True) with TestRun.step("Create temporary file on exported object."): tmp_file = create_random_test_file(f"{mount_point}/tmp.file", Size(1, Unit.GibiByte)) os_utils.sync() with TestRun.step("Flush core."): core.flush_core() os_utils.sync() with TestRun.step( f"Check {syslog_path} for flush request and delete temporary file." ): Logs.check_syslog_for_signals() tmp_file.remove(True) with TestRun.step("Turn on alru cleaning policy and set policy params."): cache.set_cleaning_policy(CleaningPolicy.alru) cache.set_params_alru( FlushParametersAlru(Time(milliseconds=5000), 10000, Time(seconds=10), Time(seconds=10))) with TestRun.step("Create big temporary file on exported object."): tmp_file = create_random_test_file(f"{mount_point}/tmp.file", Size(5, Unit.GibiByte)) os_utils.sync() with TestRun.step( "Wait for automatic flush from alru cleaning policy and check log." ): wait_time = (int( cache.get_flush_parameters_alru().staleness_time.total_seconds()) + int(cache.get_flush_parameters_alru().activity_threshold. total_seconds()) + int(cache.get_flush_parameters_alru().wake_up_time. total_seconds()) + 5) sleep(wait_time) with TestRun.step( f"Check {syslog_path} for flush request and delete temporary file." ): Logs.check_syslog_for_signals() tmp_file.remove(True) with TestRun.step("Create temporary file on exported object."): create_random_test_file(f"{mount_point}/tmp.file", Size(1, Unit.GibiByte)) os_utils.sync() with TestRun.step("Unmount exported object and remove it from cache."): core.unmount() core.remove_core() os_utils.sync() with TestRun.step(f"Check {syslog_path} for flush request."): Logs.check_syslog_for_signals() with TestRun.step("Stop cache."): cache.stop()
def test_acp_param_wake_up_time(cache_line_size, cache_mode): """ title: Functional test for ACP wake-up parameter. description: | Verify if interval between ACP cleaning iterations is not longer than wake-up time parameter value. pass_criteria: - ACP flush iterations are triggered with defined frequency. """ with TestRun.step("Test prepare."): error_threshold_ms = 50 generated_vals = get_random_list( min_val=FlushParametersAcp.acp_params_range().wake_up_time[0], max_val=FlushParametersAcp.acp_params_range().wake_up_time[1], n=10, ) acp_configs = [] for config in generated_vals: acp_configs.append( FlushParametersAcp(wake_up_time=Time(milliseconds=config))) acp_configs.append(FlushParametersAcp.default_acp_params()) with TestRun.step("Prepare partitions."): core_size = Size(10, Unit.GibiByte) cache_device = TestRun.disks["cache"] core_device = TestRun.disks["core"] cache_device.create_partitions([Size(5, Unit.GibiByte)]) core_device.create_partitions([core_size]) with TestRun.step( f"Start cache in {cache_mode} with {cache_line_size} and add core." ): cache = casadm.start_cache(cache_device.partitions[0], cache_mode, cache_line_size) core = cache.add_core(core_device.partitions[0]) with TestRun.step("Set cleaning policy to NOP."): cache.set_cleaning_policy(CleaningPolicy.nop) with TestRun.step("Start IO in background."): fio = get_fio_cmd(core, core_size) fio_pid = fio.run_in_background() time.sleep(10) with TestRun.step("Set cleaning policy to ACP."): cache.set_cleaning_policy(CleaningPolicy.acp) with TestRun.group("Verify IO number for different wake_up_time values."): for acp_config in acp_configs: with TestRun.step(f"Setting {acp_config}"): cache.set_params_acp(acp_config) accepted_interval_threshold = ( acp_config.wake_up_time.total_milliseconds() + error_threshold_ms) with TestRun.step( "Using blktrace verify if interval between ACP cleaning iterations " f"is shorter or equal than wake-up parameter value " f"(including {error_threshold_ms}ms error threshold)"): blktrace = BlkTrace(core.core_device, BlkTraceMask.write) blktrace.start_monitoring() time.sleep(15) blktrace_output = blktrace.stop_monitoring() for (prev, curr) in zip(blktrace_output, blktrace_output[1:]): if not new_acp_iteration(prev, curr): continue interval_ms = (curr.timestamp - prev.timestamp) / 10**6 if interval_ms > accepted_interval_threshold: TestRun.LOGGER.error( f"{interval_ms} is not within accepted range for " f"{acp_config.wake_up_time.total_milliseconds()} " f"wake_up_time param value.") with TestRun.step("Stop all caches"): kill_all_io() casadm.stop_all_caches()
def test_load_x_to_one_diff_params(cache_mode, cleaning_policy, cache_line_size, cores_amount): """ title: Test for loading CAS with 1 cache and 1 or 4 cores with different params. description: | Verify that loading cache configurations works properly in every mode with 1 cache and 1 or 4 cores. Use different parameters with load command. pass_criteria: - OpenCAS should load successfully but with saved configuration. - No errors in cache are found. """ with TestRun.step(f"Prepare 1 cache and {cores_amount} core devices"): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(512, Unit.MebiByte)]) cache_dev = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_size = [] for i in range(cores_amount): core_size.append(Size(1, Unit.GibiByte)) core_dev.create_partitions(core_size) with TestRun.step(f"Start cache with {cores_amount} cores."): cache = casadm.start_cache(cache_dev, cache_mode[0], cache_line_size[0], force=True) id_cache = cache.cache_id cores = [] for i in range(cores_amount): cores.append(cache.add_core(core_dev.partitions[i])) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != cores_amount: TestRun.fail( f"Expected cores count: {cores_amount}; Actual cores count: {cores_count}." ) with TestRun.step("Configure cleaning policy."): cache.set_cleaning_policy(cleaning_policy) if cleaning_policy == CleaningPolicy.alru: alru = FlushParametersAlru() alru.activity_threshold = Time(milliseconds=1000) alru.flush_max_buffers = 10 alru.staleness_time = Time(seconds=60) alru.wake_up_time = Time(seconds=5) cache.set_params_alru(alru) if cleaning_policy == CleaningPolicy.acp: acp = FlushParametersAcp() acp.flush_max_buffers = 100 acp.wake_up_time = Time(seconds=5) cache.set_params_acp(acp) with TestRun.step("Run FIO on exported object"): fio = (Fio().create_command().io_engine( IoEngine.libaio).io_depth(64).direct().read_write( ReadWrite.randrw).size(Size(1, Unit.GibiByte)).block_size( cache_line_size[0]).read_write(ReadWrite.randrw).num_jobs( cores_amount).cpus_allowed_policy( CpusAllowedPolicy.split)) for core in cores: fio.add_job(f"job_{core.core_id}").target(core.path) fio.run() with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail( f"There are still {caches_count} caches running after stopping service." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail( f"There are still {cores_count} cores running after stopping service." ) with TestRun.step("Load cache."): try: cache = casadm.start_cache(cache_dev, cache_mode[1], cache_line_size[1], id_cache + 1, load=True) except Exception: TestRun.LOGGER.error("Cannot pass other cache ID to cache load.") TestRun.LOGGER.info( "Load cache without passing cache ID to command.") cache = casadm.start_cache(cache_dev, cache_mode[1], cache_line_size[1], load=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != cores_amount: TestRun.fail( f"Expected cores count: {cores_amount}; Actual cores count: {cores_count}." ) with TestRun.step("Compare cache configuration before and after load."): if cache_mode[0] != cache.get_cache_mode(): TestRun.fail("Cache modes are different. Should be the same.") if cache_line_size[0] != cache.get_cache_line_size(): TestRun.fail("Cache line sizes are different. Should be the same.") if id_cache != cache.cache_id: TestRun.fail("Cache IDs are different. Should be the same.") if cleaning_policy != cache.get_cleaning_policy(): TestRun.fail("Cleaning policies are different.") if cleaning_policy == CleaningPolicy.alru: if alru != cache.get_flush_parameters_alru(): TestRun.fail("Cleaning policy parameters are different.") if cleaning_policy == CleaningPolicy.acp: if acp != cache.get_flush_parameters_acp(): TestRun.fail("Cleaning policy parameters are different.") with TestRun.step("Run FIO again on exported object"): fio = (Fio().create_command().io_engine( IoEngine.libaio).io_depth(64).direct().read_write( ReadWrite.randrw).size(Size(1, Unit.GibiByte)).block_size( cache_line_size[1]).read_write(ReadWrite.randrw).num_jobs( cores_amount).cpus_allowed_policy( CpusAllowedPolicy.split)) for core in cores: fio.add_job(f"job_{core.core_id}").target(core.path) fio.run() with TestRun.step("Check if there are no error statistics."): if cache.get_statistics().error_stats.total_errors != 0: TestRun.fail("There are errors in the cache.") with TestRun.step("Stop caches."): casadm.stop_all_caches()