@@ -94,21 +94,27 @@ def pytest_addoption(parser: "Parser"):
9494def cleanup_hanged_docker_containers () -> None :
9595 try :
9696 client : DockerClient = docker .from_env ()
97- for container in client .containers .list ():
98- if container .name == "pytest_mysql_to_sqlite3" :
99- container .kill ()
100- break
97+ try :
98+ for container in client .containers .list ():
99+ if container .name == "pytest_mysql_to_sqlite3" :
100+ container .kill ()
101+ break
102+ finally :
103+ client .close ()
101104 except Exception :
102105 pass
103106
104107
105- def pytest_keyboard_interrupt () -> None :
108+ def pytest_keyboard_interrupt (excinfo : t . Any ) -> None :
106109 try :
107110 client : DockerClient = docker .from_env ()
108- for container in client .containers .list ():
109- if container .name == "pytest_mysql_to_sqlite3" :
110- container .kill ()
111- break
111+ try :
112+ for container in client .containers .list ():
113+ if container .name == "pytest_mysql_to_sqlite3" :
114+ container .kill ()
115+ break
116+ finally :
117+ client .close ()
112118 except Exception :
113119 pass
114120
@@ -195,6 +201,7 @@ def mysql_credentials(pytestconfig: Config) -> MySQLCredentials:
195201
196202@pytest .fixture (scope = "session" )
197203def mysql_instance (mysql_credentials : MySQLCredentials , pytestconfig : Config ) -> t .Iterator [MySQLConnection ]:
204+ client : t .Optional [DockerClient ] = None
198205 container : t .Optional [Container ] = None
199206 mysql_connection : t .Optional [t .Union [PooledMySQLConnection , MySQLConnectionAbstract ]] = None
200207 mysql_available : bool = False
@@ -215,62 +222,69 @@ def mysql_instance(mysql_credentials: MySQLCredentials, pytestconfig: Config) ->
215222 except Exception as err :
216223 pytest .fail (str (err ))
217224
218- docker_mysql_image = pytestconfig .getoption ("docker_mysql_image" ) or "mysql:latest"
219-
220- if not any (docker_mysql_image in image .tags for image in client .images .list ()):
221- print (f"Attempting to download Docker image { docker_mysql_image } '" )
222- try :
223- client .images .pull (docker_mysql_image )
224- except (HTTPError , NotFound ) as err :
225- pytest .fail (str (err ))
226-
227- container = client .containers .run (
228- image = docker_mysql_image ,
229- name = "pytest_mysql_to_sqlite3" ,
230- ports = {"3306/tcp" : (mysql_credentials .host , f"{ mysql_credentials .port } /tcp" )},
231- environment = {
232- "MYSQL_RANDOM_ROOT_PASSWORD" : "yes" ,
233- "MYSQL_USER" : mysql_credentials .user ,
234- "MYSQL_PASSWORD" : mysql_credentials .password ,
235- "MYSQL_DATABASE" : mysql_credentials .database ,
236- },
237- command = [
238- "--character-set-server=utf8mb4" ,
239- "--collation-server=utf8mb4_unicode_ci" ,
240- ],
241- detach = True ,
242- auto_remove = True ,
243- )
244-
245- while not mysql_available and mysql_connection_retries > 0 :
246- try :
247- mysql_connection = mysql .connector .connect (
248- user = mysql_credentials .user ,
249- password = mysql_credentials .password ,
250- host = mysql_credentials .host ,
251- port = mysql_credentials .port ,
252- charset = "utf8mb4" ,
253- collation = "utf8mb4_unicode_ci" ,
225+ try :
226+ if use_docker :
227+ docker_mysql_image = pytestconfig .getoption ("docker_mysql_image" ) or "mysql:latest"
228+
229+ if not any (docker_mysql_image in image .tags for image in client .images .list ()):
230+ print (f"Attempting to download Docker image { docker_mysql_image } '" )
231+ try :
232+ client .images .pull (docker_mysql_image )
233+ except (HTTPError , NotFound ) as err :
234+ pytest .fail (str (err ))
235+
236+ container = client .containers .run (
237+ image = docker_mysql_image ,
238+ name = "pytest_mysql_to_sqlite3" ,
239+ ports = {"3306/tcp" : (mysql_credentials .host , f"{ mysql_credentials .port } /tcp" )},
240+ environment = {
241+ "MYSQL_RANDOM_ROOT_PASSWORD" : "yes" ,
242+ "MYSQL_USER" : mysql_credentials .user ,
243+ "MYSQL_PASSWORD" : mysql_credentials .password ,
244+ "MYSQL_DATABASE" : mysql_credentials .database ,
245+ },
246+ command = [
247+ "--character-set-server=utf8mb4" ,
248+ "--collation-server=utf8mb4_unicode_ci" ,
249+ ],
250+ detach = True ,
251+ auto_remove = True ,
254252 )
255- except mysql .connector .Error as err :
256- if err .errno == errorcode .CR_SERVER_LOST :
257- # sleep for two seconds and retry the connection
258- sleep (2 )
259- else :
260- raise
261- finally :
262- mysql_connection_retries -= 1
263- if mysql_connection and mysql_connection .is_connected ():
264- mysql_available = True
265- mysql_connection .close ()
266- else :
267- if not mysql_available and mysql_connection_retries <= 0 :
268- raise ConnectionAbortedError ("Maximum MySQL connection retries exhausted! Are you sure MySQL is running?" )
269-
270- yield # type: ignore[misc]
271253
272- if use_docker and container is not None :
273- container .kill ()
254+ while not mysql_available and mysql_connection_retries > 0 :
255+ try :
256+ mysql_connection = mysql .connector .connect (
257+ user = mysql_credentials .user ,
258+ password = mysql_credentials .password ,
259+ host = mysql_credentials .host ,
260+ port = mysql_credentials .port ,
261+ charset = "utf8mb4" ,
262+ collation = "utf8mb4_unicode_ci" ,
263+ )
264+ except mysql .connector .Error as err :
265+ if err .errno == errorcode .CR_SERVER_LOST :
266+ # sleep for two seconds and retry the connection
267+ sleep (2 )
268+ else :
269+ raise
270+ finally :
271+ mysql_connection_retries -= 1
272+ if mysql_connection and mysql_connection .is_connected ():
273+ mysql_available = True
274+ mysql_connection .close ()
275+ else :
276+ if not mysql_available and mysql_connection_retries <= 0 :
277+ raise ConnectionAbortedError ("Maximum MySQL connection retries exhausted! Are you sure MySQL is running?" )
278+
279+ yield # type: ignore[misc]
280+ finally :
281+ if use_docker :
282+ try :
283+ if container is not None :
284+ container .kill ()
285+ finally :
286+ if client is not None :
287+ client .close ()
274288
275289
276290class MySQLSSLCerts (t .NamedTuple ):
0 commit comments