diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index 4c6dd94..b5ece0f 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -569,7 +569,7 @@ class Cache: def free_device_config(self, cfg): lib = OcfLib.getInstance().ocf_volume_destroy(cfg._volume) - def attach_device( + def attach_device_async( self, device, force=False, @@ -593,15 +593,40 @@ class Cache: self.write_lock() - c = OcfCompletion([("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]) + def callback(c): + self.write_unlock() + self.free_device_config(device_config) + + c = OcfCompletion( + [("cache", c_void_p), ("priv", c_void_p), ("error", c_int)], + callback=callback + ) self.owner.lib.ocf_mngt_cache_attach(self.cache_handle, byref(attach_cfg), c, None) + + return c + + def attach_device( + self, + device, + force=False, + perform_test=False, + cache_line_size=None, + open_cores=False, + disable_cleaner=False, + ): + + c = self.attach_device_async( + device, + force, + perform_test, + cache_line_size, + open_cores, + disable_cleaner + ) + c.wait() - self.write_unlock() - - self.free_device_config(device_config) - if c.results["error"]: raise OcfError( f"Attaching cache device failed", diff --git a/tests/functional/pyocf/types/shared.py b/tests/functional/pyocf/types/shared.py index a4cd19a..4f1c5de 100644 --- a/tests/functional/pyocf/types/shared.py +++ b/tests/functional/pyocf/types/shared.py @@ -83,7 +83,7 @@ class OcfCompletion: except KeyError: raise KeyError(f"No completion argument {key} specified") - def __init__(self, completion_args: list, context=None): + def __init__(self, completion_args: list, context=None, callback=None): """ Provide ctypes arg list, and optionally index of status argument in completion function which will be extracted (default - last argument). @@ -95,6 +95,7 @@ class OcfCompletion: self.results = OcfCompletion.CompletionResult(completion_args) self._as_parameter_ = self.callback self.context = context + self.user_callback = callback @property def callback(self): @@ -102,6 +103,8 @@ class OcfCompletion: def complete(*args): self.results.results = args self.e.set() + if self.user_callback: + self.user_callback(self) return complete diff --git a/tests/functional/tests/engine/test_d2c.py b/tests/functional/tests/engine/test_d2c.py index 5fb6710..f1a0fde 100644 --- a/tests/functional/tests/engine/test_d2c.py +++ b/tests/functional/tests/engine/test_d2c.py @@ -4,6 +4,7 @@ # +from time import sleep import pytest @@ -18,7 +19,6 @@ from pyocf.utils import Size CORE_SIZE = 4096 -@pytest.mark.xfail(reason="Data corruption when switching from D2C") def test_d2c_io(pyocf_ctx): """ Start cache in D2C @@ -46,7 +46,8 @@ def test_d2c_io(pyocf_ctx): d2c_data.write(b"a" * CORE_SIZE, CORE_SIZE) d2c_io.set_data(d2c_data) - cache.attach_device(cache_device) + c = cache.attach_device_async(cache_device) + sleep(1) wt_io = vol.new_io(queue, 0, CORE_SIZE, IoDir.WRITE, 0, 0) wt_data = Data(CORE_SIZE) @@ -55,11 +56,19 @@ def test_d2c_io(pyocf_ctx): wt_completion = Sync(wt_io).submit() assert int(wt_completion.results["err"]) == 0 - assert cache.get_stats()["req"]["wr_full_misses"]["value"] == 1 d2c_completion = Sync(d2c_io).submit() assert int(d2c_completion.results["err"]) == 0 - assert cache.get_stats()["req"]["wr_pt"]["value"] == 1 + + c.wait() + + if c.results["error"]: + raise OcfError( + f"Attaching cache device failed", + c.results["error"], + ) + + assert cache.get_stats()["req"]["wr_pt"]["value"] == 2 read_io = vol.new_io(queue, 0, CORE_SIZE, IoDir.READ, 0, 0) read_data = Data(CORE_SIZE) @@ -67,6 +76,7 @@ def test_d2c_io(pyocf_ctx): read_completion = Sync(read_io).submit() assert int(read_completion.results["err"]) == 0 + assert cache.get_stats()["req"]["rd_full_misses"]["value"] == 1 cache.stop()