testutil: extract find_one_subclass_in_module() helper

A small refactor to avoid shipping this duplicated code (this
one is easy to extract/reuse).
This commit is contained in:
Michael Vogt 2024-03-25 10:13:36 +01:00 committed by Achilleas Koutsou
parent 79360b529a
commit 1d4f2dc53b
3 changed files with 22 additions and 20 deletions

View file

@ -1,4 +1,3 @@
import inspect
import os
import pathlib
from types import ModuleType
@ -28,14 +27,7 @@ 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]
service_cls = testutil.find_one_subclass_in_module(inputs_module, inputs.InputService)
fd = testutil.make_fake_service_fd()
srv_obj = service_cls.from_args(["--service-fd", str(fd)])
return srv_obj

View file

@ -2,6 +2,7 @@
Test related utilities
"""
import contextlib
import inspect
import os
import pathlib
import re
@ -10,6 +11,8 @@ import socket
import subprocess
import tempfile
import textwrap
from types import ModuleType
from typing import Type
def has_executable(executable: str) -> bool:
@ -168,3 +171,18 @@ def make_fake_service_fd() -> int:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
fd = os.dup(sock.fileno())
return fd
def find_one_subclass_in_module(module: ModuleType, subclass: Type) -> object:
"""Find the class in the given module that is a subclass of the given input
If multiple classes are found an error is raised.
"""
cls = None
for name, memb in inspect.getmembers(
module,
predicate=lambda obj: inspect.isclass(obj) and issubclass(obj, subclass)):
if cls:
raise ValueError(f"already have {cls}, also found {name}:{memb}")
cls = memb
return cls

View file

@ -1,4 +1,3 @@
import inspect
import os
import pathlib
from types import ModuleType
@ -28,14 +27,7 @@ def sources_service(sources_module) -> ModuleType:
"""sources_service is a fixture that imports a sources module by its name
defined in SOURCES_NAME in the test module and returns a SourcesService
"""
service_cls = None
for memb in inspect.getmembers(
sources_module,
predicate=lambda obj: inspect.isclass(obj) and issubclass(
obj, sources.SourceService)):
if service_cls:
raise ValueError(f"already have {service_cls}, also found {memb}")
service_cls = memb[1]
service_cls = testutil.find_one_subclass_in_module(sources_module, sources.SourceService)
fd = testutil.make_fake_service_fd()
services_obj = service_cls.from_args(["--service-fd", str(fd)])
return services_obj
srv_obj = service_cls.from_args(["--service-fd", str(fd)])
return srv_obj