diff --git a/tests/functional/tests/management/test_composite_volume.py b/tests/functional/tests/management/test_composite_volume.py index eae42d3..19ee523 100644 --- a/tests/functional/tests/management/test_composite_volume.py +++ b/tests/functional/tests/management/test_composite_volume.py @@ -4,9 +4,16 @@ # import pytest +from ctypes import c_int + +from pyocf.types.volume import RamVolume, ErrorDevice, TraceDevice, IoFlags +from pyocf.types.cvolume import CVolume +from pyocf.types.data import Data +from pyocf.types.io import IoDir +from pyocf.types.shared import OcfError, OcfCompletion +from pyocf.utils import Size as S -@pytest.mark.skip(reason="not implemented") def test_create_composite_volume(pyocf_ctx): """ title: Create composite volume. @@ -26,10 +33,12 @@ def test_create_composite_volume(pyocf_ctx): - composite_volume::creation - composite_volume::adding_component_volume """ - pass + cvol = CVolume(pyocf_ctx) + vol = RamVolume(S.from_MiB(1)) + cvol.add(vol) + cvol.destroy() -@pytest.mark.skip(reason="not implemented") def test_add_subvolumes_of_different_types(pyocf_ctx): """ title: Add subvolumes of different types. @@ -49,10 +58,16 @@ def test_add_subvolumes_of_different_types(pyocf_ctx): requirements: - composite_volume::component_volume_types """ - pass + vol1 = RamVolume(S.from_MiB(1)) + vol2_backend = RamVolume(S.from_MiB(1)) + vol2 = ErrorDevice(vol2_backend) + + cvol = CVolume(pyocf_ctx) + cvol.add(vol1) + cvol.add(vol2) + cvol.destroy() -@pytest.mark.skip(reason="not implemented") def test_add_max_subvolumes(pyocf_ctx): """ title: Add maximum number of subvolumes. @@ -69,10 +84,36 @@ def test_add_max_subvolumes(pyocf_ctx): requirements: - composite_volume::max_composite_volumes """ - pass + + cvol = CVolume(pyocf_ctx) + + for i in range(16): + vol = RamVolume(S.from_MiB(1)) + cvol.add(vol) + + vol = RamVolume(S.from_MiB(1)) + with pytest.raises(OcfError): + cvol.add(vol) + + cvol.destroy() + + +def _cvol_io(cvol, addr, size, func, flags=0): + io = cvol.new_io( + queue=None, addr=addr, length=size, direction=IoDir.WRITE, io_class=0, flags=flags, + ) + completion = OcfCompletion([("err", c_int)]) + io.callback = completion.callback + data = Data(byte_count=size) + io.set_data(data, 0) + + submit_fn = getattr(io, func) + submit_fn() + completion.wait() + + return int(completion.results["err"]) -@pytest.mark.skip(reason="not implemented") def test_basic_volume_operations(pyocf_ctx): """ title: Perform basic volume operations. @@ -93,7 +134,56 @@ def test_basic_volume_operations(pyocf_ctx): - composite_volume::volume_api - composite_volume::io_request_passing """ - pass + count = {"flush": 0, "discard": 0, "io": 0} + expected = {"flush": 0, "discard": 0, "io": 0} + + pyocf_ctx.register_volume_type(TraceDevice) + + addr = S.from_KiB(512).B + size = S.from_KiB(4).B + + def trace(vol, io, io_type): + if io_type == TraceDevice.IoType.Flush or int(io.contents._flags) & IoFlags.FLUSH: + count["flush"] += 1 + elif io_type == TraceDevice.IoType.Discard: + count["discard"] += 1 + else: + assert io_type == TraceDevice.IoType.Data + count["io"] += 1 + assert io.contents._dir == IoDir.WRITE + assert io.contents._addr == addr + assert io.contents._bytes == size + + return True + + backend = RamVolume(S.from_MiB(1)) + trace_dev = TraceDevice(backend, trace_fcn=trace) + + cvol = CVolume(pyocf_ctx) + + cvol.add(trace_dev) + cvol.open() + + # verify data properly propagated + ret = _cvol_io(cvol, addr, size, "submit") + assert ret == 0 + expected["io"] += 1 + assert expected == count + + # verify flush properly propagated + ret = _cvol_io(cvol, addr, size, "submit_flush", IoFlags.FLUSH) + assert ret == 0 + expected["flush"] += 1 + assert expected == count + + # verify discard properly propagated + ret = _cvol_io(cvol, addr, size, "submit_discard") + assert ret == 0 + expected["discard"] += 1 + assert expected == count + + cvol.close() + cvol.destroy() @pytest.mark.skip(reason="not implemented")