inputs: add inputs_service fixture
This new fixture avoids some repetitivness when building tests for input services.
This commit is contained in:
parent
5f31ccf9f2
commit
7c0e9cfcf7
2 changed files with 25 additions and 8 deletions
|
|
@ -1,14 +1,16 @@
|
||||||
|
import inspect
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from osbuild import inputs, testutil
|
||||||
from osbuild.testutil.imports import import_module_from_path
|
from osbuild.testutil.imports import import_module_from_path
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture(name="inputs_module")
|
||||||
def inputs_module(request: pytest.FixtureRequest) -> ModuleType:
|
def inputs_module_fixture(request: pytest.FixtureRequest) -> ModuleType:
|
||||||
"""inputs_module is a fixture that imports a stage module by its name
|
"""inputs_module is a fixture that imports a stage module by its name
|
||||||
defined in INPUTS_NAME in the test module.
|
defined in INPUTS_NAME in the test module.
|
||||||
"""
|
"""
|
||||||
|
|
@ -19,3 +21,21 @@ def inputs_module(request: pytest.FixtureRequest) -> ModuleType:
|
||||||
caller_dir = pathlib.Path(request.node.fspath).parent
|
caller_dir = pathlib.Path(request.node.fspath).parent
|
||||||
module_path = caller_dir.parent / inputs_name
|
module_path = caller_dir.parent / inputs_name
|
||||||
return import_module_from_path("inputs", os.fspath(module_path))
|
return import_module_from_path("inputs", os.fspath(module_path))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def inputs_service(inputs_module) -> ModuleType:
|
||||||
|
"""inputs_service is a fixture that imports a inputs module by its name
|
||||||
|
defined in INPUTS_NAME in the test module and returns a InputService
|
||||||
|
"""
|
||||||
|
service_cls = None
|
||||||
|
for memb in inspect.getmembers(
|
||||||
|
inputs_module,
|
||||||
|
predicate=lambda obj: inspect.isclass(obj) and issubclass(
|
||||||
|
obj, inputs.InputService)):
|
||||||
|
if service_cls:
|
||||||
|
raise ValueError(f"already have {service_cls}, also found {memb}")
|
||||||
|
service_cls = memb[1]
|
||||||
|
fd = testutil.make_fake_service_fd()
|
||||||
|
srv_obj = service_cls.from_args(["--service-fd", str(fd)])
|
||||||
|
return srv_obj
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import tempfile
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from osbuild import testutil
|
|
||||||
from osbuild.testutil import has_executable, make_container
|
from osbuild.testutil import has_executable, make_container
|
||||||
|
|
||||||
INPUTS_NAME = "org.osbuild.containers-storage"
|
INPUTS_NAME = "org.osbuild.containers-storage"
|
||||||
|
|
@ -26,7 +25,7 @@ class FakeStoreClient:
|
||||||
|
|
||||||
@pytest.mark.skipif(not has_executable("podman"), reason="no podman executable")
|
@pytest.mark.skipif(not has_executable("podman"), reason="no podman executable")
|
||||||
@pytest.mark.skipif(os.getuid() != 0, reason="root only")
|
@pytest.mark.skipif(os.getuid() != 0, reason="root only")
|
||||||
def test_containers_local_inputs_integration(tmp_path, inputs_module):
|
def test_containers_local_inputs_integration(tmp_path, inputs_service):
|
||||||
with make_container(tmp_path, {"file1": "file1 content"}) as base_tag:
|
with make_container(tmp_path, {"file1": "file1 content"}) as base_tag:
|
||||||
image_id = subprocess.check_output(
|
image_id = subprocess.check_output(
|
||||||
["podman", "inspect", "-f", "{{ .Id }}", base_tag],
|
["podman", "inspect", "-f", "{{ .Id }}", base_tag],
|
||||||
|
|
@ -40,8 +39,6 @@ def test_containers_local_inputs_integration(tmp_path, inputs_module):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fd = testutil.make_fake_service_fd()
|
|
||||||
cnt_inputs = inputs_module.ContainersStorageInput.from_args(["--service-fd", str(fd)])
|
|
||||||
store = FakeStoreClient(tmp_path / "fake-sources")
|
store = FakeStoreClient(tmp_path / "fake-sources")
|
||||||
# not using "tmp_path" here as it will "rm -rf" on cleanup and
|
# not using "tmp_path" here as it will "rm -rf" on cleanup and
|
||||||
# that is dangerous as during the tests we bind mount the
|
# that is dangerous as during the tests we bind mount the
|
||||||
|
|
@ -49,12 +46,12 @@ def test_containers_local_inputs_integration(tmp_path, inputs_module):
|
||||||
target = pathlib.Path(tempfile.TemporaryDirectory("cnt-target").name)
|
target = pathlib.Path(tempfile.TemporaryDirectory("cnt-target").name)
|
||||||
options = None
|
options = None
|
||||||
try:
|
try:
|
||||||
reply = cnt_inputs.map(store, inputs["origin"], inputs["references"], target, options)
|
reply = inputs_service.map(store, inputs["origin"], inputs["references"], target, options)
|
||||||
assert reply["path"] == target
|
assert reply["path"] == target
|
||||||
assert len(reply["data"]["archives"]) == 1
|
assert len(reply["data"]["archives"]) == 1
|
||||||
assert (target / "storage").exists()
|
assert (target / "storage").exists()
|
||||||
finally:
|
finally:
|
||||||
cnt_inputs.unmap()
|
inputs_service.unmap()
|
||||||
# cleanup manually, note that we only remove empty dirs here,
|
# cleanup manually, note that we only remove empty dirs here,
|
||||||
# because we only expect a bind mount under "$target/storage"
|
# because we only expect a bind mount under "$target/storage"
|
||||||
# Anything non-empty here means a umount() failed
|
# Anything non-empty here means a umount() failed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue