Skip to content

Commit 8bd102a

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 00f0515 commit 8bd102a

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

irctest/controllers/ergo.py

Lines changed: 66 additions & 11 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,18 +277,12 @@ 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
275-
280+
def addMysqlToConfig(self, config: Dict) -> Dict:
281+
socket_path = self.startMysql()
282+
self.createMysqlDatabase(socket_path, "ergo_history")
276283
config["datastore"]["mysql"] = {
277284
"enabled": True,
278-
"host": "localhost",
279-
"user": "ergo",
280-
"password": mysql_password,
285+
"socket-path": socket_path,
281286
"history-database": "ergo_history",
282287
"timeout": "3s",
283288
}
@@ -290,6 +295,56 @@ def addMysqlToConfig(self, config: Optional[Dict] = None) -> Dict:
290295
}
291296
return config
292297

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