3
3
import os
4
4
import shutil
5
5
import subprocess
6
- from typing import Any , Dict , Optional , Set , Type , Union
6
+ from typing import Any , Dict , List , Optional , Set , Type , Union
7
7
8
8
from irctest .basecontrollers import (
9
9
BaseServerController ,
@@ -139,6 +139,7 @@ class ErgoController(BaseServerController, DirectoryBasedController):
139
139
supported_sasl_mechanisms = {"PLAIN" , "SCRAM-SHA-256" }
140
140
supports_sts = True
141
141
extban_mute_char = "m"
142
+ mysql_proc : Optional [subprocess .Popen ] = None
142
143
143
144
def create_config (self ) -> None :
144
145
super ().create_config ()
@@ -215,6 +216,16 @@ def run(
215
216
[* faketime_cmd , "ergo" , "run" , "--conf" , self ._config_path , "--quiet" ]
216
217
)
217
218
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
+
218
229
def wait_for_services (self ) -> None :
219
230
# Nothing to wait for, they start at the same time as Ergo.
220
231
pass
@@ -266,20 +277,16 @@ def addLoggingToConfig(self, config: Optional[Dict] = None) -> Dict:
266
277
config .update (LOGGING_CONFIG )
267
278
return config
268
279
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" )
275
283
config ["datastore" ]["mysql" ] = {
276
284
"enabled" : True ,
277
- "host" : "localhost" ,
278
- "user" : "ergo" ,
279
- "password" : mysql_password ,
285
+ "socket-path" : socket_path ,
280
286
"history-database" : "ergo_history" ,
281
287
"timeout" : "3s" ,
282
288
}
289
+
283
290
config ["accounts" ]["multiclient" ] = {
284
291
"enabled" : True ,
285
292
"allowed-by-default" : True ,
@@ -293,6 +300,56 @@ def addMysqlToConfig(self, config: Optional[Dict] = None) -> Dict:
293
300
}
294
301
return config
295
302
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
+
296
353
def rehash (self , case : BaseServerTestCase , config : Dict ) -> None :
297
354
self ._config = config
298
355
self ._write_config ()
0 commit comments