mirror of https://github.com/progval/irctest.git
Use pathlib to work with temporary config dirs
This commit is contained in:
parent
dbdadec677
commit
507f5b7426
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -87,7 +88,7 @@ class DirectoryBasedController(_BaseController):
|
||||||
"""Helper for controllers whose software configuration is based on an
|
"""Helper for controllers whose software configuration is based on an
|
||||||
arbitrary directory."""
|
arbitrary directory."""
|
||||||
|
|
||||||
directory: Optional[str]
|
directory: Optional[Path]
|
||||||
|
|
||||||
def __init__(self, test_config: TestCaseControllerConfig):
|
def __init__(self, test_config: TestCaseControllerConfig):
|
||||||
super().__init__(test_config)
|
super().__init__(test_config)
|
||||||
|
@ -110,22 +111,21 @@ class DirectoryBasedController(_BaseController):
|
||||||
"""Open a file in the configuration directory."""
|
"""Open a file in the configuration directory."""
|
||||||
assert self.directory
|
assert self.directory
|
||||||
if os.sep in name:
|
if os.sep in name:
|
||||||
dir_ = os.path.join(self.directory, os.path.dirname(name))
|
dir_ = self.directory / os.path.dirname(name)
|
||||||
if not os.path.isdir(dir_):
|
dir_.mkdir(parents=True, exist_ok=True)
|
||||||
os.makedirs(dir_)
|
assert dir_.is_dir()
|
||||||
assert os.path.isdir(dir_)
|
return (self.directory / name).open(mode)
|
||||||
return open(os.path.join(self.directory, name), mode)
|
|
||||||
|
|
||||||
def create_config(self) -> None:
|
def create_config(self) -> None:
|
||||||
if not self.directory:
|
if not self.directory:
|
||||||
self.directory = tempfile.mkdtemp()
|
self.directory = Path(tempfile.mkdtemp())
|
||||||
|
|
||||||
def gen_ssl(self) -> None:
|
def gen_ssl(self) -> None:
|
||||||
assert self.directory
|
assert self.directory
|
||||||
self.csr_path = os.path.join(self.directory, "ssl.csr")
|
self.csr_path = self.directory / "ssl.csr"
|
||||||
self.key_path = os.path.join(self.directory, "ssl.key")
|
self.key_path = self.directory / "ssl.key"
|
||||||
self.pem_path = os.path.join(self.directory, "ssl.pem")
|
self.pem_path = self.directory / "ssl.pem"
|
||||||
self.dh_path = os.path.join(self.directory, "dh.pem")
|
self.dh_path = self.directory / "dh.pem"
|
||||||
subprocess.check_output(
|
subprocess.check_output(
|
||||||
[
|
[
|
||||||
self.openssl_bin,
|
self.openssl_bin,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import os
|
from pathlib import Path
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
@ -101,14 +101,11 @@ class AnopeController(BaseServicesController, DirectoryBasedController):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert self.directory
|
assert self.directory
|
||||||
|
services_path = shutil.which("services")
|
||||||
|
assert services_path
|
||||||
|
|
||||||
# Config and code need to be in the same directory, *obviously*
|
# Config and code need to be in the same directory, *obviously*
|
||||||
os.symlink(
|
(self.directory / "lib").symlink_to(Path(services_path).parent.parent / "lib")
|
||||||
os.path.join(
|
|
||||||
os.path.dirname(shutil.which("services")), "..", "lib" # type: ignore
|
|
||||||
),
|
|
||||||
os.path.join(self.directory, "lib"),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.proc = subprocess.Popen(
|
self.proc = subprocess.Popen(
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Type
|
from typing import Optional, Type
|
||||||
|
|
||||||
|
@ -81,11 +80,11 @@ class AthemeController(BaseServicesController, DirectoryBasedController):
|
||||||
"atheme-services",
|
"atheme-services",
|
||||||
"-n", # don't fork
|
"-n", # don't fork
|
||||||
"-c",
|
"-c",
|
||||||
os.path.join(self.directory, "services.conf"),
|
self.directory / "services.conf",
|
||||||
"-l",
|
"-l",
|
||||||
f"/tmp/services-{server_port}.log",
|
f"/tmp/services-{server_port}.log",
|
||||||
"-p",
|
"-p",
|
||||||
os.path.join(self.directory, "services.pid"),
|
self.directory / "services.pid",
|
||||||
"-D",
|
"-D",
|
||||||
self.directory,
|
self.directory,
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import os
|
from pathlib import Path
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -80,7 +80,7 @@ oper {{
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def initialize_entropy(directory: str) -> None:
|
def initialize_entropy(directory: Path) -> None:
|
||||||
# https://github.com/DALnet/bahamut/blob/7fc039d403f66a954225c5dc4ad1fe683aedd794/include/dh.h#L35-L38
|
# https://github.com/DALnet/bahamut/blob/7fc039d403f66a954225c5dc4ad1fe683aedd794/include/dh.h#L35-L38
|
||||||
nb_rand_bytes = 512 // 8
|
nb_rand_bytes = 512 // 8
|
||||||
# https://github.com/DALnet/bahamut/blob/7fc039d403f66a954225c5dc4ad1fe683aedd794/src/dh.c#L186
|
# https://github.com/DALnet/bahamut/blob/7fc039d403f66a954225c5dc4ad1fe683aedd794/src/dh.c#L186
|
||||||
|
@ -89,7 +89,7 @@ def initialize_entropy(directory: str) -> None:
|
||||||
# Not actually random; but we don't care.
|
# Not actually random; but we don't care.
|
||||||
entropy = b"\x00" * entropy_file_size
|
entropy = b"\x00" * entropy_file_size
|
||||||
|
|
||||||
with open(os.path.join(directory, ".ircd.entropy"), "wb") as fd:
|
with (directory / ".ircd.entropy").open("wb") as fd:
|
||||||
fd.write(entropy)
|
fd.write(entropy)
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,8 +140,8 @@ class BahamutController(BaseServerController, DirectoryBasedController):
|
||||||
initialize_entropy(self.directory)
|
initialize_entropy(self.directory)
|
||||||
|
|
||||||
# they are hardcoded... thankfully Bahamut reads them from the CWD.
|
# they are hardcoded... thankfully Bahamut reads them from the CWD.
|
||||||
shutil.copy(self.pem_path, os.path.join(self.directory, "ircd.crt"))
|
shutil.copy(self.pem_path, self.directory / "ircd.crt")
|
||||||
shutil.copy(self.key_path, os.path.join(self.directory, "ircd.key"))
|
shutil.copy(self.key_path, self.directory / "ircd.key")
|
||||||
|
|
||||||
with self.open_file("server.conf") as fd:
|
with self.open_file("server.conf") as fd:
|
||||||
fd.write(
|
fd.write(
|
||||||
|
@ -168,7 +168,7 @@ class BahamutController(BaseServerController, DirectoryBasedController):
|
||||||
"ircd",
|
"ircd",
|
||||||
"-t", # don't fork
|
"-t", # don't fork
|
||||||
"-f",
|
"-f",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set
|
from typing import Optional, Set
|
||||||
|
@ -88,9 +87,9 @@ class BaseHybridController(BaseServerController, DirectoryBasedController):
|
||||||
self.binary_name,
|
self.binary_name,
|
||||||
"-foreground",
|
"-foreground",
|
||||||
"-configfile",
|
"-configfile",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
"-pidfile",
|
"-pidfile",
|
||||||
os.path.join(self.directory, "server.pid"),
|
self.directory / "server.pid",
|
||||||
],
|
],
|
||||||
# stderr=subprocess.DEVNULL,
|
# stderr=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
|
|
|
@ -185,21 +185,19 @@ class ErgoController(BaseServerController, DirectoryBasedController):
|
||||||
bind_address = "127.0.0.1:%s" % (port,)
|
bind_address = "127.0.0.1:%s" % (port,)
|
||||||
listener_conf = None # plaintext
|
listener_conf = None # plaintext
|
||||||
if ssl:
|
if ssl:
|
||||||
self.key_path = os.path.join(self.directory, "ssl.key")
|
self.key_path = self.directory / "ssl.key"
|
||||||
self.pem_path = os.path.join(self.directory, "ssl.pem")
|
self.pem_path = self.directory / "ssl.pem"
|
||||||
listener_conf = {"tls": {"cert": self.pem_path, "key": self.key_path}}
|
listener_conf = {"tls": {"cert": self.pem_path, "key": self.key_path}}
|
||||||
config["server"]["listeners"][bind_address] = listener_conf # type: ignore
|
config["server"]["listeners"][bind_address] = listener_conf # type: ignore
|
||||||
|
|
||||||
config["datastore"]["path"] = os.path.join( # type: ignore
|
config["datastore"]["path"] = str(self.directory / "ircd.db") # type: ignore
|
||||||
self.directory, "ircd.db"
|
|
||||||
)
|
|
||||||
|
|
||||||
if password is not None:
|
if password is not None:
|
||||||
config["server"]["password"] = hash_password(password) # type: ignore
|
config["server"]["password"] = hash_password(password) # type: ignore
|
||||||
|
|
||||||
assert self.proc is None
|
assert self.proc is None
|
||||||
|
|
||||||
self._config_path = os.path.join(self.directory, "server.yml")
|
self._config_path = self.directory / "server.yml"
|
||||||
self._config = config
|
self._config = config
|
||||||
self._write_config()
|
self._write_config()
|
||||||
subprocess.call(["ergo", "initdb", "--conf", self._config_path, "--quiet"])
|
subprocess.call(["ergo", "initdb", "--conf", self._config_path, "--quiet"])
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -164,7 +163,7 @@ class InspircdController(BaseServerController, DirectoryBasedController):
|
||||||
"inspircd",
|
"inspircd",
|
||||||
"--nofork",
|
"--nofork",
|
||||||
"--config",
|
"--config",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
],
|
],
|
||||||
stdout=subprocess.DEVNULL,
|
stdout=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -68,7 +67,7 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
|
||||||
self.create_config()
|
self.create_config()
|
||||||
password_field = password if password else ""
|
password_field = password if password else ""
|
||||||
assert self.directory
|
assert self.directory
|
||||||
pidfile = os.path.join(self.directory, "ircd.pid")
|
pidfile = self.directory / "ircd.pid"
|
||||||
with self.open_file("server.conf") as fd:
|
with self.open_file("server.conf") as fd:
|
||||||
fd.write(
|
fd.write(
|
||||||
TEMPLATE_CONFIG.format(
|
TEMPLATE_CONFIG.format(
|
||||||
|
@ -93,7 +92,7 @@ class Irc2Controller(BaseServerController, DirectoryBasedController):
|
||||||
"-p",
|
"-p",
|
||||||
"on",
|
"on",
|
||||||
"-f",
|
"-f",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
],
|
],
|
||||||
# stderr=subprocess.DEVNULL,
|
# stderr=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -87,7 +86,7 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
|
||||||
self.create_config()
|
self.create_config()
|
||||||
password_field = 'password = "{}";'.format(password) if password else ""
|
password_field = 'password = "{}";'.format(password) if password else ""
|
||||||
assert self.directory
|
assert self.directory
|
||||||
pidfile = os.path.join(self.directory, "ircd.pid")
|
pidfile = self.directory / "ircd.pid"
|
||||||
with self.open_file("server.conf") as fd:
|
with self.open_file("server.conf") as fd:
|
||||||
fd.write(
|
fd.write(
|
||||||
TEMPLATE_CONFIG.format(
|
TEMPLATE_CONFIG.format(
|
||||||
|
@ -110,7 +109,7 @@ class Ircu2Controller(BaseServerController, DirectoryBasedController):
|
||||||
"ircd",
|
"ircd",
|
||||||
"-n", # don't detach
|
"-n", # don't detach
|
||||||
"-f",
|
"-f",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
"-x",
|
"-x",
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Type
|
from typing import Optional, Type
|
||||||
|
|
||||||
|
@ -85,9 +84,7 @@ class LimnoriaController(BaseClientController, DirectoryBasedController):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
assert self.directory
|
assert self.directory
|
||||||
self.proc = subprocess.Popen(
|
self.proc = subprocess.Popen(["supybot", self.directory / "bot.conf"])
|
||||||
["supybot", os.path.join(self.directory, "bot.conf")]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_irctest_controller_class() -> Type[LimnoriaController]:
|
def get_irctest_controller_class() -> Type[LimnoriaController]:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -128,7 +127,7 @@ class MammonController(BaseServerController, DirectoryBasedController):
|
||||||
"mammond",
|
"mammond",
|
||||||
"--nofork", # '--debug',
|
"--nofork", # '--debug',
|
||||||
"--config",
|
"--config",
|
||||||
os.path.join(self.directory, "server.yml"),
|
self.directory / "server.yml",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -94,7 +93,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
|
||||||
password_field=password_field,
|
password_field=password_field,
|
||||||
key_path=self.key_path,
|
key_path=self.key_path,
|
||||||
pem_path=self.pem_path,
|
pem_path=self.pem_path,
|
||||||
empty_file=os.path.join(self.directory, "empty.txt"),
|
empty_file=self.directory / "empty.txt",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ class NgircdController(BaseServerController, DirectoryBasedController):
|
||||||
"ngircd",
|
"ngircd",
|
||||||
"--nodaemon",
|
"--nodaemon",
|
||||||
"--config",
|
"--config",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
],
|
],
|
||||||
# stdout=subprocess.DEVNULL,
|
# stdout=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, Set, Type
|
from typing import Optional, Set, Type
|
||||||
|
@ -86,7 +85,7 @@ class SnircdController(BaseServerController, DirectoryBasedController):
|
||||||
self.create_config()
|
self.create_config()
|
||||||
password_field = 'password = "{}";'.format(password) if password else ""
|
password_field = 'password = "{}";'.format(password) if password else ""
|
||||||
assert self.directory
|
assert self.directory
|
||||||
pidfile = os.path.join(self.directory, "ircd.pid")
|
pidfile = self.directory / "ircd.pid"
|
||||||
with self.open_file("server.conf") as fd:
|
with self.open_file("server.conf") as fd:
|
||||||
fd.write(
|
fd.write(
|
||||||
TEMPLATE_CONFIG.format(
|
TEMPLATE_CONFIG.format(
|
||||||
|
@ -109,7 +108,7 @@ class SnircdController(BaseServerController, DirectoryBasedController):
|
||||||
"ircd",
|
"ircd",
|
||||||
"-n", # don't detach
|
"-n", # don't detach
|
||||||
"-f",
|
"-f",
|
||||||
os.path.join(self.directory, "server.conf"),
|
self.directory / "server.conf",
|
||||||
"-x",
|
"-x",
|
||||||
"DEBUG",
|
"DEBUG",
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import os
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
from typing import Optional, TextIO, Type, cast
|
from typing import Optional, TextIO, Type, cast
|
||||||
|
@ -38,14 +38,14 @@ class SopelController(BaseClientController):
|
||||||
super().kill()
|
super().kill()
|
||||||
if self.filename:
|
if self.filename:
|
||||||
try:
|
try:
|
||||||
os.unlink(os.path.join(os.path.expanduser("~/.sopel/"), self.filename))
|
(Path("~/.sopel/").expanduser() / self.filename).unlink()
|
||||||
except OSError: # File does not exist
|
except OSError: # File does not exist
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def open_file(self, filename: str, mode: str = "a") -> TextIO:
|
def open_file(self, filename: str, mode: str = "a") -> TextIO:
|
||||||
dir_path = os.path.expanduser("~/.sopel/")
|
dir_path = Path("~/.sopel/").expanduser()
|
||||||
os.makedirs(dir_path, exist_ok=True)
|
dir_path.mkdir(parents=True, exist_ok=True)
|
||||||
return cast(TextIO, open(os.path.join(dir_path, filename), mode))
|
return cast(TextIO, (dir_path / filename).open(mode))
|
||||||
|
|
||||||
def create_config(self) -> None:
|
def create_config(self) -> None:
|
||||||
with self.open_file(self.filename):
|
with self.open_file(self.filename):
|
||||||
|
|
|
@ -5,7 +5,7 @@ import shutil
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import Optional, Set, Type
|
from typing import List, Optional, Set, Type, Union
|
||||||
|
|
||||||
from irctest.basecontrollers import (
|
from irctest.basecontrollers import (
|
||||||
BaseServerController,
|
BaseServerController,
|
||||||
|
@ -222,20 +222,20 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
|
||||||
password_field=password_field,
|
password_field=password_field,
|
||||||
key_path=self.key_path,
|
key_path=self.key_path,
|
||||||
pem_path=self.pem_path,
|
pem_path=self.pem_path,
|
||||||
empty_file=os.path.join(self.directory, "empty.txt"),
|
empty_file=self.directory / "empty.txt",
|
||||||
extras=extras,
|
extras=extras,
|
||||||
set_extras=set_extras,
|
set_extras=set_extras,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
proot_cmd = []
|
proot_cmd: List[Union[str, pathlib.Path]] = []
|
||||||
self.using_proot = False
|
self.using_proot = False
|
||||||
if shutil.which("proot"):
|
if shutil.which("proot"):
|
||||||
unrealircd_path = shutil.which("unrealircd")
|
unrealircd_path = shutil.which("unrealircd")
|
||||||
if unrealircd_path:
|
if unrealircd_path:
|
||||||
unrealircd_prefix = pathlib.Path(unrealircd_path).parents[1]
|
unrealircd_prefix = pathlib.Path(unrealircd_path).parents[1]
|
||||||
tmpdir = os.path.join(self.directory, "tmp")
|
tmpdir = self.directory / "tmp"
|
||||||
os.mkdir(tmpdir)
|
tmpdir.mkdir()
|
||||||
# Unreal cleans its tmp/ directory after each run, which prevents
|
# Unreal cleans its tmp/ directory after each run, which prevents
|
||||||
# multiple processes from running at the same time.
|
# multiple processes from running at the same time.
|
||||||
# Using PRoot, we can isolate them, with a tmp/ directory for each
|
# Using PRoot, we can isolate them, with a tmp/ directory for each
|
||||||
|
@ -258,7 +258,7 @@ class UnrealircdController(BaseServerController, DirectoryBasedController):
|
||||||
"-t",
|
"-t",
|
||||||
"-F", # BOOT_NOFORK
|
"-F", # BOOT_NOFORK
|
||||||
"-f",
|
"-f",
|
||||||
os.path.join(self.directory, "unrealircd.conf"),
|
self.directory / "unrealircd.conf",
|
||||||
],
|
],
|
||||||
# stdout=subprocess.DEVNULL,
|
# stdout=subprocess.DEVNULL,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue