@@ -57,7 +57,7 @@ def control_port():
5757 import re
5858 import subprocess
5959 import time
60- from typing import List , Optional
60+ from typing import Any , Dict , List , Optional
6161
6262 # Silence warnings caused by passing a pytest fixture to another fixture.
6363 # pylint: disable=redefined-outer-name
@@ -271,3 +271,98 @@ def shell(env, system_test_dir, logger):
271271 def perl (env , system_test_dir , logger ):
272272 """Function to call a perl script with arguments."""
273273 return partial (_run_script , env , logger , system_test_dir , env ["PERL" ])
274+
275+ @pytest .fixture (scope = "module" , autouse = True )
276+ def system_test ( # pylint: disable=too-many-arguments,too-many-statements
277+ request ,
278+ env : Dict [str , str ],
279+ logger ,
280+ system_test_dir ,
281+ shell ,
282+ perl ,
283+ ):
284+ """
285+ Driver of the test setup/teardown process. Used automatically for every test module.
286+
287+ This is the most important one-fixture-to-rule-them-all. Note the
288+ autouse=True which causes this fixture to be loaded by every test
289+ module without the need to explicitly specify it.
290+
291+ When this fixture is used, it utilizes other fixtures, such as
292+ system_test_dir, which handles the creation of the temporary test
293+ directory.
294+
295+ Afterwards, it checks the test environment and takes care of starting
296+ the servers. When everything is ready, that's when the actual tests are
297+ executed. Once that is done, this fixture stops the servers and checks
298+ for any artifacts indicating an issue (e.g. coredumps).
299+
300+ Finally, when this fixture reaches an end (or encounters an exception,
301+ which may be caused by fail/skip invocations), any fixtures which is
302+ used by this one are finalized - e.g. system_test_dir performs final
303+ checks and cleans up the temporary test directory.
304+ """
305+
306+ def check_net_interfaces ():
307+ try :
308+ perl ("testsock.pl" , ["-p" , env ["PORT" ]])
309+ except subprocess .CalledProcessError as exc :
310+ logger .error ("testsock.pl: exited with code %d" , exc .returncode )
311+ pytest .skip ("Network interface aliases not set up." )
312+
313+ def check_prerequisites ():
314+ try :
315+ shell (f"{ system_test_dir } /prereq.sh" )
316+ except FileNotFoundError :
317+ pass # prereq.sh is optional
318+ except subprocess .CalledProcessError :
319+ pytest .skip ("Prerequisites missing." )
320+
321+ def setup_test ():
322+ try :
323+ shell (f"{ system_test_dir } /setup.sh" )
324+ except FileNotFoundError :
325+ pass # setup.sh is optional
326+ except subprocess .CalledProcessError as exc :
327+ logger .error ("Failed to run test setup" )
328+ pytest .fail (f"setup.sh exited with { exc .returncode } " )
329+
330+ def start_servers ():
331+ try :
332+ perl ("start.pl" , ["--port" , env ["PORT" ], system_test_dir .name ])
333+ except subprocess .CalledProcessError as exc :
334+ logger .error ("Failed to start servers" )
335+ pytest .fail (f"start.pl exited with { exc .returncode } " )
336+
337+ def stop_servers ():
338+ try :
339+ perl ("stop.pl" , [system_test_dir .name ])
340+ except subprocess .CalledProcessError as exc :
341+ logger .error ("Failed to stop servers" )
342+ pytest .fail (f"stop.pl exited with { exc .returncode } " )
343+
344+ def get_core_dumps ():
345+ try :
346+ shell ("get_core_dumps.sh" , [system_test_dir .name ])
347+ except subprocess .CalledProcessError as exc :
348+ logger .error ("Found core dumps" )
349+ pytest .fail (f"get_core_dumps.sh exited with { exc .returncode } " )
350+
351+ os .environ .update (env ) # Ensure pytests have the same env vars as shell tests.
352+ logger .info (f"test started: { request .node .name } " )
353+ port = int (env ["PORT" ])
354+ logger .info ("using port range: <%d, %d>" , port , port + PORTS_PER_TEST - 1 )
355+
356+ # Perform checks which may skip this test.
357+ check_net_interfaces ()
358+ check_prerequisites ()
359+
360+ setup_test ()
361+ try :
362+ start_servers ()
363+ logger .debug ("executing test(s)" )
364+ yield
365+ finally :
366+ logger .debug ("test(s) finished" )
367+ stop_servers ()
368+ get_core_dumps ()
0 commit comments