Skip to content

Commit 0e1ea42

Browse files
committed
ergo: Create MySQL subprocess instead of using external DB
This starts each test with a clean database, so we can remove chan/nick randomization from stateful tests (chathistory and roleplay). It will also allow testing Ergo with a MySQL backend for the KV store instead of buntdb. Additionally, this makes it much easier to run these tests, than having to manually configure such a database.
1 parent 5371077 commit 0e1ea42

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

irctest/controllers/ergo.py

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import shutil
55
import subprocess
6-
from typing import Any, Dict, Optional, Set, Type, Union
6+
from typing import Any, Dict, List, Optional, Set, Type, Union
77

88
from irctest.basecontrollers import (
99
BaseServerController,
@@ -139,6 +139,7 @@ class ErgoController(BaseServerController, DirectoryBasedController):
139139
supported_sasl_mechanisms = {"PLAIN", "SCRAM-SHA-256"}
140140
supports_sts = True
141141
extban_mute_char = "m"
142+
mysql_proc: Optional[subprocess.Popen] = None
142143

143144
def create_config(self) -> None:
144145
super().create_config()
@@ -215,6 +216,16 @@ def run(
215216
[*faketime_cmd, "ergo", "run", "--conf", self._config_path, "--quiet"]
216217
)
217218

219+
def terminate(self) -> None:
220+
if self.mysql_proc is not None:
221+
self.mysql_proc.terminate()
222+
super().terminate()
223+
224+
def kill(self) -> None:
225+
if self.mysql_proc is not None:
226+
self.mysql_proc.kill()
227+
super().kill()
228+
218229
def wait_for_services(self) -> None:
219230
# Nothing to wait for, they start at the same time as Ergo.
220231
pass
@@ -266,20 +277,16 @@ def addLoggingToConfig(self, config: Optional[Dict] = None) -> Dict:
266277
config.update(LOGGING_CONFIG)
267278
return config
268279

269-
def addMysqlToConfig(self, config: Optional[Dict] = None) -> Dict:
270-
mysql_password = os.getenv("MYSQL_PASSWORD")
271-
if config is None:
272-
config = self.baseConfig()
273-
if not mysql_password:
274-
return config
280+
def addMysqlToConfig(self, config: Dict) -> Dict:
281+
socket_path = self.startMysql()
282+
self.createMysqlDatabase(socket_path, "ergo_history")
275283
config["datastore"]["mysql"] = {
276284
"enabled": True,
277-
"host": "localhost",
278-
"user": "ergo",
279-
"password": mysql_password,
285+
"socket-path": socket_path,
280286
"history-database": "ergo_history",
281287
"timeout": "3s",
282288
}
289+
283290
config["accounts"]["multiclient"] = {
284291
"enabled": True,
285292
"allowed-by-default": True,
@@ -293,6 +300,56 @@ def addMysqlToConfig(self, config: Optional[Dict] = None) -> Dict:
293300
}
294301
return config
295302

303+
def startMysql(self) -> str:
304+
"""Starts a new MySQL server listening on a UNIX socket, returns the socket
305+
path"""
306+
assert self.directory
307+
mysql_dir = os.path.join(self.directory, "mysql")
308+
socket_path = os.path.join(mysql_dir, "mysql.socket")
309+
os.mkdir(mysql_dir)
310+
311+
print("Starting MySQL...")
312+
self.mysql_proc = subprocess.Popen(
313+
[
314+
"mysqld",
315+
"--no-defaults",
316+
"--tmpdir=" + mysql_dir,
317+
"--datadir=" + mysql_dir,
318+
"--socket=" + socket_path,
319+
"--skip-networking",
320+
"--skip-grant-tables",
321+
],
322+
stdout=subprocess.PIPE,
323+
stderr=subprocess.STDOUT,
324+
)
325+
326+
mysql_stdout = self.mysql_proc.stdout
327+
assert mysql_stdout is not None # for mypy...
328+
lines: List[bytes] = []
329+
while self.mysql_proc.returncode is None:
330+
line = mysql_stdout.readline()
331+
lines.append(lines)
332+
if b"mysqld: ready for connections." in line:
333+
break
334+
assert self.mysql_proc.returncode is None, (
335+
"MySQL unexpected stopped: " + b"\n".join(lines).decode()
336+
)
337+
print("MySQL started")
338+
339+
return socket_path
340+
341+
def createMysqlDatabase(self, socket_path: str, database_name: str) -> None:
342+
subprocess.check_call(
343+
[
344+
"mysql",
345+
"--no-defaults",
346+
"-S",
347+
socket_path,
348+
"-e",
349+
f"CREATE DATABASE {database_name};",
350+
]
351+
)
352+
296353
def rehash(self, case: BaseServerTestCase, config: Dict) -> None:
297354
self._config = config
298355
self._write_config()

irctest/server_tests/chathistory.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
# Keep this in sync with validate_chathistory()
1919
SUBCOMMANDS = ["LATEST", "BEFORE", "AFTER", "BETWEEN", "AROUND"]
2020

21-
MYSQL_PASSWORD = ""
22-
2321

2422
def validate_chathistory_batch(msgs):
2523
batch_tag = None

0 commit comments

Comments
 (0)