def test_surprise_shutdown_stop_cache(pyocf_ctx): core_device = RamVolume(S.from_MiB(10)) error_triggered = True error_io_seq_no = 0 io_offset = mngmt_op_surprise_shutdown_test_io_offset while error_triggered: # Start cache device without error injection error_io = {IoDir.WRITE: error_io_seq_no} device = ErrorDevice( mngmt_op_surprise_shutdown_test_cache_size, error_seq_no=error_io, armed=False ) # setup cache and insert some data cache = Cache.start_on_device(device, cache_mode=CacheMode.WB) core = Core(device=core_device) cache.add_core(core) vol = CoreVolume(core, open=True) ocf_write(vol, cache.get_default_queue(), 0xAA, io_offset) # start error injection device.arm() try: cache.stop() status = OcfErrorCode.OCF_OK except OcfError as ex: status = ex.error_code # if error was injected we expect mngmt op error error_triggered = device.error_triggered() if error_triggered: assert status == OcfErrorCode.OCF_ERR_WRITE_CACHE else: assert status == 0 if not error_triggered: break # disable error injection and load the cache device.disarm() cache = None assert core_device.get_bytes()[io_offset] == VOLUME_POISON cache = Cache.load_from_device(device, open_cores=False) stats = cache.get_stats() if stats["conf"]["core_count"] == 1: assert stats["usage"]["occupancy"]["value"] == 1 core = Core(device=core_device) cache.add_core(core, try_add=True) vol = CoreVolume(core, open=True) assert ocf_read(vol, cache.get_default_queue(), io_offset) == 0xAA cache.stop() # advance error injection point error_io_seq_no += 1
def test_surprise_shutdown_cache_reinit(pyocf_ctx): core_device = RamVolume(S.from_MiB(10)) error_io = {IoDir.WRITE: 0} io_offset = mngmt_op_surprise_shutdown_test_io_offset error_triggered = True while error_triggered: # Start cache device without error injection device = ErrorDevice( mngmt_op_surprise_shutdown_test_cache_size, error_seq_no=error_io, armed=False ) # start WB cache = Cache.start_on_device(device, cache_mode=CacheMode.WB) core = Core(device=core_device) cache.add_core(core) vol = CoreVolume(core, open=True) queue = cache.get_default_queue() # insert dirty cacheline ocf_write(vol, queue, 0xAA, io_offset) cache.stop() assert core_device.get_bytes()[io_offset] == VOLUME_POISON # start error injection device.arm() # power failure during cache re-initialization try: # sets force = True by default cache = Cache.start_on_device(device, cache_mode=CacheMode.WB) status = OcfErrorCode.OCF_OK except OcfError as ex: status = ex.error_code cache = None error_triggered = device.error_triggered() assert error_triggered == (status == OcfErrorCode.OCF_ERR_WRITE_CACHE) if cache: with pytest.raises(OcfError) as ex: cache.stop() assert ex.value.error_code == OcfErrorCode.OCF_ERR_WRITE_CACHE device.disarm() cache = None status = OcfErrorCode.OCF_OK try: cache = Cache.load_from_device(device) except OcfError as ex: status = ex.error_code if not cache: assert status == OcfErrorCode.OCF_ERR_NO_METADATA else: stats = cache.get_stats() if stats["conf"]["core_count"] == 0: assert stats["usage"]["occupancy"]["value"] == 0 cache.add_core(core) vol = CoreVolume(core, open=True) assert ocf_read(vol, cache.get_default_queue(), io_offset) == VOLUME_POISON cache.stop() error_io[IoDir.WRITE] += 1