55import argparse
66import os
77import shutil
8+ import subprocess
89import sys
910from typing import Any , Dict , List , Optional , Tuple
1011
1516
1617from decoder import decoder
1718
18- from .compose import get_test_root , INSTANCE_DIRECTORY
19+ from .compose import get_test_root , INSTANCE_DIRECTORY , DEFAULT_TEST_TIMEOUT_S
1920from .compose import Compose
2021
2122# Where can we expect to find Job definitions?
@@ -295,6 +296,30 @@ def _check(t_compose: Compose,
295296 return True
296297
297298
299+ def _run_nextflow (command : str , project_path : str )\
300+ -> Tuple [int , str , str ]:
301+ """Runs nextflow in the project directory returning the exit code,
302+ stdout and stderr.
303+ """
304+ assert command
305+ assert project_path
306+
307+ cwd = os .getcwd ()
308+ os .chdir (project_path )
309+
310+ try :
311+ test = subprocess .run (command .split (),
312+ capture_output = True ,
313+ timeout = DEFAULT_TEST_TIMEOUT_S ,
314+ check = False )
315+ finally :
316+ os .chdir (cwd )
317+
318+ return test .returncode ,\
319+ test .stdout .decode ("utf-8" ),\
320+ test .stderr .decode ("utf-8" )
321+
322+
298323def _test (args : argparse .Namespace ,
299324 collection : str ,
300325 job : str ,
@@ -325,10 +350,6 @@ def _test(args: argparse.Namespace,
325350 else :
326351 job_image_type = _DEFAULT_IMAGE_TYPE
327352
328- # Exclude nextflow image types for now.
329- if job_image_type in [_IMAGE_TYPE_NEXTFLOW ]:
330- return tests_passed , tests_skipped , tests_ignored , tests_failed
331-
332353 for job_test_name in job_definition .tests :
333354
334355 # If a job test has been named,
@@ -437,6 +458,7 @@ def _test(args: argparse.Namespace,
437458 job_variables [variable ] = os .path .basename (value )
438459 input_files .append (value )
439460
461+ decoded_command : str = ''
440462 if test_status :
441463
442464 # Job variables must contain 'built-in' variables: -
@@ -462,11 +484,14 @@ def _test(args: argparse.Namespace,
462484 # Create the test directories, docker-compose file
463485 # and copy inputs...
464486 t_compose : Optional [Compose ] = None
487+ job_command : str = ''
488+ project_path : str = ''
465489 if test_status :
466490
467491 # The command must not contain new-lines.
468492 # So split then join the command.
469- job_command : str = '' .join (decoded_command .splitlines ())
493+ assert decoded_command
494+ job_command = '' .join (decoded_command .splitlines ())
470495
471496 print (f'> image={ job_image } ' )
472497 print (f'> image-type={ job_image_type } ' )
@@ -483,7 +508,7 @@ def _test(args: argparse.Namespace,
483508 job_working_directory ,
484509 job_command ,
485510 args .run_as_user )
486- project_path : str = t_compose .create ()
511+ project_path = t_compose .create ()
487512
488513 test_path : str = t_compose .get_test_path ()
489514 print (f'# path={ test_path } ' )
@@ -496,37 +521,44 @@ def _test(args: argparse.Namespace,
496521 # Run the container
497522 if test_status and not args .dry_run :
498523
524+ exit_code : int = 0
525+ out : str = ''
526+ err : str = ''
499527 if job_image_type in [_IMAGE_TYPE_SIMPLE ]:
500528 # Run the image container
501529 assert t_compose
502530 exit_code , out , err = t_compose .run ()
503531 elif job_image_type in [_IMAGE_TYPE_NEXTFLOW ]:
504532 # Run nextflow directly
505- pass
506-
507- # Delete the test directory?
508- # Not if there's an error
509- # and not if told not to.
510- expected_exit_code : int = \
511- job_definition .tests [job_test_name ].checks .exitCode
512-
513- if exit_code != expected_exit_code :
533+ assert job_command
534+ assert project_path
535+ exit_code , out , err = _run_nextflow (job_command , project_path )
536+ else :
514537 print ('! FAILURE' )
515- print (f'! exit_code={ exit_code } '
516- f' expected_exit_code={ expected_exit_code } ' )
517- print ('! Container stdout follows...' )
518- print (out )
519- print ('! Container stderr follows...' )
520- print (err )
538+ print (f'! unsupported image-type ({ job_image_type } ' )
521539 test_status = False
522540
541+ if test_status :
542+ expected_exit_code : int = \
543+ job_definition .tests [job_test_name ].checks .exitCode
544+
545+ if exit_code != expected_exit_code :
546+ print ('! FAILURE' )
547+ print (f'! exit_code={ exit_code } '
548+ f' expected_exit_code={ expected_exit_code } ' )
549+ print ('! Test stdout follows...' )
550+ print (out )
551+ print ('! Test stderr follows...' )
552+ print (err )
553+ test_status = False
554+
523555 if args .verbose :
524556 print (out )
525557
526558 # Inspect the results
527559 # (only if successful so far)
528- if test_status \
529- and not args .dry_run \
560+ if test_status \
561+ and not args .dry_run \
530562 and job_definition .tests [job_test_name ].checks .outputs :
531563
532564 assert t_compose
0 commit comments