def test_expanding_convert_inputs(self): overlay = os.path.abspath( package_path('src/mavis_config/overlay.json')) main = os.path.abspath(package_path('src/mavis_config/config.json')) conf = { 'reference.annotations': [EXISTING_FILE], 'skip_stage.validate': True, 'reference.reference_genome': [EXISTING_FILE], 'libraries': { 'AAAA': { 'disease_status': 'diseased', 'protocol': 'genome', 'assign': ['dlly'], } }, 'convert': { 'dlly': { 'file_type': 'delly', 'inputs': [package_path('src/mavis_config/*.json')], } }, 'output_dir': '.', } validate_config( conf, stage='setup', ) assert conf['libraries']['AAAA']['assign'] == ['dlly'] assert conf['convert']['dlly']['inputs'] == [main, overlay]
def test_missing_output_dir_for_convert(self): with pytest.raises(WorkflowError) as err: conf = { 'reference.annotations': [EXISTING_FILE], 'skip_stage.validate': True, 'reference.reference_genome': [EXISTING_FILE], 'libraries': { 'AAAA': { 'disease_status': 'diseased', 'protocol': 'genome', 'assign': ['dlly'], } }, 'convert': { 'dlly': { 'file_type': 'delly', 'inputs': [package_path('src/mavis_config/*.json')], } }, } validate_config( conf, stage='setup', ) assert 'missing required property: output_dir' in str(err)
def test_error_on_missing_libraries(self): with pytest.raises(WorkflowError) as err: validate_config( { 'reference.annotations': [EXISTING_FILE], 'reference.aligner_reference': [EXISTING_FILE], 'reference.reference_genome': [EXISTING_FILE], }, stage='setup', ) assert 'missing required property: libraries' in str(err)
def test_library_missing_assign(self): with pytest.raises(WorkflowError) as err: conf = validate_config( { 'reference.annotations': [EXISTING_FILE], 'skip_stage.validate': True, 'reference.reference_genome': [EXISTING_FILE], 'libraries': { 'AAAA': { 'disease_status': 'diseased', 'protocol': 'genome' } }, }, stage='setup', ) assert 'ValidationError: \'assign\' is a required property' in str(err)
def main(argv: Optional[List[str]] = None): """ sets up the parser and checks the validity of command line args loads reference files and redirects into subcommand main functions Args: argv: List of arguments, defaults to command line arguments """ if argv is None: # need to do at run time or patching will not behave as expected argv = sys.argv[1:] start_time = int(time.time()) parser, args = create_parser(argv) if args.command == SUBCOMMAND.OVERLAY: args = check_overlay_args(args, parser) log_conf = { 'format': '{asctime} [{levelname}] {message}', 'style': '{', 'level': args.log_level, } original_logging_handlers = logging.root.handlers[:] for handler in logging.root.handlers: logging.root.removeHandler(handler) if args.log: # redirect stdout AND stderr to a log file log_conf['filename'] = args.log logging.basicConfig(**log_conf) _util.logger.info(f'MAVIS: {__version__}') _util.logger.info(f'hostname: {platform.node()}') _util.log_arguments(args) config: Dict = dict() try: if args.command != SUBCOMMAND.CONVERT: with open(args.config, 'r') as fh: config = json.load(fh) validate_config( config, args.command, ) except AttributeError as err: raise err if args.command == SUBCOMMAND.VALIDATE: args.aligner_version = get_aligner_version(config['validate.aligner']) # try checking the input files exist try: args.inputs = _util.bash_expands(*args.inputs) except AttributeError: pass except FileNotFoundError: parser.error('--inputs file(s) for {} {} do not exist'.format( args.command, args.inputs)) # decide which main function to execute command = args.command try: if command == SUBCOMMAND.CLUSTER: cluster_main.main( inputs=args.inputs, output=args.output, start_time=start_time, config=config, library=args.library, ) elif command == SUBCOMMAND.VALIDATE: validate_main.main( inputs=args.inputs, output=args.output, start_time=start_time, config=config, library=args.library, ) elif command == SUBCOMMAND.ANNOTATE: annotate_main.main( inputs=args.inputs, output=args.output, start_time=start_time, config=config, library=args.library, ) elif command == SUBCOMMAND.PAIR: pairing_main.main( inputs=args.inputs, output=args.output, start_time=start_time, config=config, ) elif command == SUBCOMMAND.SUMMARY: summary_main.main( inputs=args.inputs, output=args.output, start_time=start_time, config=config, ) elif command == SUBCOMMAND.CONVERT: convert_main( args.inputs, args.outputfile, args.file_type, args.strand_specific, args.assume_no_untemplated, ) elif command == SUBCOMMAND.SETUP: # add bam stats to the config if missing if not config.get('skip_stage.validate'): _config.add_bamstats_to_config(config) _util.logger.info(f'writing: {args.outputfile}') with open(args.outputfile, 'w') as fh: fh.write(json.dumps(config, sort_keys=True, indent=' ')) else: overlay_main( buffer_length=args.buffer_length, gene_name=args.gene_name, markers=args.markers, read_depth_plots=args.read_depth_plots, config=config, output=args.output, ) duration = int(time.time()) - start_time hours = duration - duration % 3600 minutes = duration - hours - (duration - hours) % 60 seconds = duration - hours - minutes _util.logger.info('run time (hh/mm/ss): {}:{:02d}:{:02d}'.format( hours // 3600, minutes // 60, seconds)) _util.logger.info(f'run time (s): {duration}') except Exception as err: raise err finally: try: for handler in logging.root.handlers: logging.root.removeHandler(handler) for handler in original_logging_handlers: logging.root.addHandler(handler) except Exception as err: print(err)
def test_error_on_missing_aligner_reference(self): with pytest.raises(WorkflowError) as err: validate_config({'reference.annotations': [EXISTING_FILE]}, stage='setup') assert 'missing required property: reference.aligner_reference' in str( err)
def test_ok_with_required(self): with not_raises(WorkflowError): validate_config( {'reference.annotations': [EXISTING_FILE]}, stage='overlay', )
def test_error_on_missing_required(self): with pytest.raises(WorkflowError): validate_config({}, stage='overlay')