Add CLI option --services-controller to allow alternatives to Atheme (none for now)

+ fix some issues with killing services processes
This commit is contained in:
2021-07-07 13:30:16 +02:00
committed by Val Lorentz
parent 54a911c2f5
commit 7e024b9ead
7 changed files with 82 additions and 20 deletions

View File

@ -94,25 +94,45 @@ flakes:
pyflakes3 irctest pyflakes3 irctest
charybdis: charybdis:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.charybdis -k '$(CHARYBDIS_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.charybdis \
--services-controller=irctest.controllers.atheme_services \
-k '$(CHARYBDIS_SELECTORS)'
ergo: ergo:
$(PYTEST) $(PYTEST_ARGS) --controller irctest.controllers.ergo -k "$(ERGO_SELECTORS)" $(PYTEST) $(PYTEST_ARGS) \
--controller irctest.controllers.ergo \
-k "$(ERGO_SELECTORS)"
inspircd: inspircd:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.inspircd -k '$(INSPIRCD_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.inspircd \
--services-controller=irctest.controllers.atheme_services \
-k '$(INSPIRCD_SELECTORS)'
limnoria: limnoria:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.limnoria -k '$(LIMNORIA_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.limnoria \
-k '$(LIMNORIA_SELECTORS)'
mammon: mammon:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.mammon -k '$(MAMMON_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.mammon \
-k '$(MAMMON_SELECTORS)'
solanum: solanum:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.solanum -k '$(SOLANUM_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.solanum \
--services-controller=irctest.controllers.atheme_services \
-k '$(SOLANUM_SELECTORS)'
sopel: sopel:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.sopel -k '$(SOPEL_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.sopel \
-k '$(SOPEL_SELECTORS)'
unrealircd: unrealircd:
$(PYTEST) $(PYTEST_ARGS) --controller=irctest.controllers.unrealircd -k '$(UNREALIRCD_SELECTORS)' $(PYTEST) $(PYTEST_ARGS) \
--controller=irctest.controllers.unrealircd \
--services-controller=irctest.controllers.atheme_services \
-k '$(UNREALIRCD_SELECTORS)'

View File

@ -12,6 +12,9 @@ def pytest_addoption(parser):
parser.addoption( parser.addoption(
"--controller", help="Which module to use to run the tested software." "--controller", help="Which module to use to run the tested software."
) )
parser.addoption(
"--services-controller", help="Which module to use to run a services package."
)
parser.addoption( parser.addoption(
"--openssl-bin", type=str, default="openssl", help="The openssl binary to use" "--openssl-bin", type=str, default="openssl", help="The openssl binary to use"
) )
@ -20,6 +23,7 @@ def pytest_addoption(parser):
def pytest_configure(config): def pytest_configure(config):
"""Called by pytest, after it parsed the command-line.""" """Called by pytest, after it parsed the command-line."""
module_name = config.getoption("controller") module_name = config.getoption("controller")
services_module_name = config.getoption("services_controller")
if module_name is None: if module_name is None:
print("Missing --controller option, errors may occur.") print("Missing --controller option, errors may occur.")
@ -35,6 +39,9 @@ def pytest_configure(config):
controller_class = module.get_irctest_controller_class() controller_class = module.get_irctest_controller_class()
if issubclass(controller_class, BaseClientController): if issubclass(controller_class, BaseClientController):
from irctest import client_tests as module from irctest import client_tests as module
if services_module_name is not None:
pytest.exit("You may not use --services-controller for client tests.")
elif issubclass(controller_class, BaseServerController): elif issubclass(controller_class, BaseServerController):
from irctest import server_tests as module from irctest import server_tests as module
else: else:
@ -45,6 +52,16 @@ def pytest_configure(config):
), ),
1, 1,
) )
if services_module_name is not None:
try:
services_module = importlib.import_module(services_module_name)
except ImportError:
pytest.exit("Cannot import module {}".format(services_module_name), 1)
controller_class.services_controller_class = (
services_module.get_irctest_controller_class()
)
_IrcTestCase.controllerClass = controller_class _IrcTestCase.controllerClass = controller_class
_IrcTestCase.controllerClass.openssl_bin = config.getoption("openssl_bin") _IrcTestCase.controllerClass.openssl_bin = config.getoption("openssl_bin")
_IrcTestCase.show_io = True # TODO _IrcTestCase.show_io = True # TODO

View File

@ -7,7 +7,7 @@ import socket
import subprocess import subprocess
import tempfile import tempfile
import time import time
from typing import IO, Any, Callable, Dict, List, Optional, Set from typing import IO, Any, Callable, Dict, List, Optional, Set, Type
import irctest import irctest
@ -182,7 +182,8 @@ class BaseServerController(_BaseController):
port_open = False port_open = False
port: int port: int
hostname: str hostname: str
services_controller: BaseServicesController services_controller: Optional[BaseServicesController] = None
services_controller_class: Type[BaseServicesController]
extban_mute_char: Optional[str] = None extban_mute_char: Optional[str] = None
"""Character used for the 'mute' extban""" """Character used for the 'mute' extban"""
@ -205,7 +206,7 @@ class BaseServerController(_BaseController):
username: str, username: str,
password: Optional[str] = None, password: Optional[str] = None,
) -> None: ) -> None:
if self.services_controller: if self.services_controller is not None:
self.services_controller.registerUser(case, username, password) self.services_controller.registerUser(case, username, password)
else: else:
raise NotImplementedByController("account registration") raise NotImplementedByController("account registration")
@ -232,8 +233,19 @@ class BaseServerController(_BaseController):
continue continue
def wait_for_services(self) -> None: def wait_for_services(self) -> None:
assert self.services_controller
self.services_controller.wait_for_services() self.services_controller.wait_for_services()
def terminate(self) -> None:
if self.services_controller is not None:
self.services_controller.terminate() # type: ignore
super().terminate() # type: ignore
def kill(self) -> None:
if self.services_controller is not None:
self.services_controller.kill() # type: ignore
super().kill()
class BaseServicesController(_BaseController): class BaseServicesController(_BaseController):
def __init__( def __init__(
@ -246,6 +258,9 @@ class BaseServicesController(_BaseController):
self.server_controller = server_controller self.server_controller = server_controller
self.services_up = False self.services_up = False
def run(self, protocol: str, server_hostname: str, server_port: int) -> None:
raise NotImplementedError("BaseServerController.run()")
def wait_for_services(self) -> None: def wait_for_services(self) -> None:
if self.services_up: if self.services_up:
# Don't check again if they are already available # Don't check again if they are already available

View File

@ -1,6 +1,6 @@
import os import os
import subprocess import subprocess
from typing import Optional from typing import Optional, Type
import irctest import irctest
from irctest.basecontrollers import BaseServicesController, DirectoryBasedController from irctest.basecontrollers import BaseServicesController, DirectoryBasedController
@ -52,12 +52,15 @@ saslserv {{
""" """
class AthemeServices(BaseServicesController, DirectoryBasedController): class AthemeController(BaseServicesController, DirectoryBasedController):
"""Mixin for server controllers that rely on Atheme""" """Mixin for server controllers that rely on Atheme"""
def run(self, protocol: str, server_hostname: str, server_port: int) -> None: def run(self, protocol: str, server_hostname: str, server_port: int) -> None:
self.create_config() self.create_config()
if protocol == "inspircd3":
# That's the name used by Anope
protocol = "inspircd"
assert protocol in ("inspircd", "charybdis", "unreal4") assert protocol in ("inspircd", "charybdis", "unreal4")
with self.open_file("services.conf") as fd: with self.open_file("services.conf") as fd:
@ -100,3 +103,7 @@ class AthemeServices(BaseServicesController, DirectoryBasedController):
raise irctest.runner.NotImplementedByController("Passwords over 288 bytes") raise irctest.runner.NotImplementedByController("Passwords over 288 bytes")
super().registerUser(case, username, password) super().registerUser(case, username, password)
def get_irctest_controller_class() -> Type[AthemeController]:
return AthemeController

View File

@ -7,7 +7,6 @@ from irctest.basecontrollers import (
DirectoryBasedController, DirectoryBasedController,
NotImplementedByController, NotImplementedByController,
) )
from irctest.controllers.atheme_services import AthemeServices
from irctest.irc_utils.junkdrawer import find_hostname_and_port from irctest.irc_utils.junkdrawer import find_hostname_and_port
TEMPLATE_CONFIG = """ TEMPLATE_CONFIG = """
@ -134,7 +133,9 @@ class CharybdisController(BaseServerController, DirectoryBasedController):
if run_services: if run_services:
self.wait_for_port() self.wait_for_port()
self.services_controller = AthemeServices(self.test_config, self) self.services_controller = self.services_controller_class(
self.test_config, self
)
self.services_controller.run( self.services_controller.run(
protocol="charybdis", server_hostname=hostname, server_port=port protocol="charybdis", server_hostname=hostname, server_port=port
) )

View File

@ -7,7 +7,6 @@ from irctest.basecontrollers import (
DirectoryBasedController, DirectoryBasedController,
NotImplementedByController, NotImplementedByController,
) )
from irctest.controllers.atheme_services import AthemeServices
from irctest.irc_utils.junkdrawer import find_hostname_and_port from irctest.irc_utils.junkdrawer import find_hostname_and_port
TEMPLATE_CONFIG = """ TEMPLATE_CONFIG = """
@ -131,9 +130,11 @@ class InspircdController(BaseServerController, DirectoryBasedController):
if run_services: if run_services:
self.wait_for_port() self.wait_for_port()
self.services_controller = AthemeServices(self.test_config, self) self.services_controller = self.services_controller_class(
self.test_config, self
)
self.services_controller.run( self.services_controller.run(
protocol="inspircd", protocol="inspircd3",
server_hostname=services_hostname, server_hostname=services_hostname,
server_port=services_port, server_port=services_port,
) )

View File

@ -7,7 +7,6 @@ from irctest.basecontrollers import (
DirectoryBasedController, DirectoryBasedController,
NotImplementedByController, NotImplementedByController,
) )
from irctest.controllers.atheme_services import AthemeServices
from irctest.irc_utils.junkdrawer import find_hostname_and_port from irctest.irc_utils.junkdrawer import find_hostname_and_port
TEMPLATE_CONFIG = """ TEMPLATE_CONFIG = """
@ -179,7 +178,9 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
if run_services: if run_services:
self.wait_for_port() self.wait_for_port()
self.services_controller = AthemeServices(self.test_config, self) self.services_controller = self.services_controller_class(
self.test_config, self
)
self.services_controller.run( self.services_controller.run(
protocol="unreal4", protocol="unreal4",
server_hostname=services_hostname, server_hostname=services_hostname,