@@ -57,7 +57,7 @@ def control_port():
57
57
import re
58
58
import subprocess
59
59
import time
60
- from typing import List , Optional
60
+ from typing import Any , Dict , List , Optional
61
61
62
62
# Silence warnings caused by passing a pytest fixture to another fixture.
63
63
# pylint: disable=redefined-outer-name
@@ -271,3 +271,98 @@ def shell(env, system_test_dir, logger):
271
271
def perl (env , system_test_dir , logger ):
272
272
"""Function to call a perl script with arguments."""
273
273
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