def test_active_samples_on_flow_cell(
    active_flow_cell_store: Store,
    flowcell_name: str,
    active_wipe_demultiplex_api: DeleteDemuxAPI,
):
    """Test if the function to find active samples works correctly"""
    # GIVEN a flowcell with active samples related to it
    store_: Store = active_flow_cell_store

    samples_on_flow_cell: List[Sample] = (store_.query(Flowcell).filter(
        Flowcell.name == flowcell_name).first().samples)

    assert samples_on_flow_cell
    for sample in samples_on_flow_cell:
        active: bool = store_.active_sample(internal_id=sample.internal_id)
        assert active

    # WHEN checking for active samples on flowcell
    active_wipe_demultiplex_api._set_samples_on_flow_cell()
    active_samples_on_flow_cell: Optional[
        List[str]] = active_wipe_demultiplex_api.active_samples_on_flow_cell()

    # THEN there should be active samples found
    assert any(sample.internal_id in active_samples_on_flow_cell
               for sample in samples_on_flow_cell)
示例#2
0
def demultiplex_flowcell(
    context: CGConfig,
    dry_run: bool,
    flowcell_id: str,
    bcl_converter: str,
):
    """Demultiplex a flowcell on slurm using CG

    flowcell-id is the flowcell run directory name, e.g. '201203_A00689_0200_AHVKJCDRXX'
    """

    LOG.info("Running cg demultiplex flowcell, using %s.", bcl_converter)
    flowcell_directory: Path = Path(context.demultiplex.run_dir) / flowcell_id

    demultiplex_api: DemultiplexingAPI = context.demultiplex_api
    demultiplex_api.set_dry_run(dry_run=dry_run)
    LOG.info(f"SETTING FLOWCELL ID TO {flowcell_id}")
    LOG.info(f"SETTING OUT DIR TO {demultiplex_api.out_dir}")

    try:
        flowcell_obj = Flowcell(flowcell_path=flowcell_directory,
                                bcl_converter=bcl_converter)
    except FlowcellError as e:
        raise click.Abort from e

    delete_demux_api: DeleteDemuxAPI = DeleteDemuxAPI(
        config=context,
        demultiplex_base=demultiplex_api.out_dir,
        dry_run=dry_run,
        run_path=flowcell_directory,
    )

    delete_demux_api.delete_flow_cell(
        cg_stats=True,
        demultiplexing_dir=True,
        run_dir=False,
        housekeeper=True,
        init_files=True,
        status_db=False,
    )

    if not demultiplex_api.is_demultiplexing_possible(
            flowcell=flowcell_obj) and not dry_run:
        LOG.warning("Can not start demultiplexing!")
        return

    if not flowcell_obj.validate_sample_sheet():
        LOG.warning(
            "Malformed sample sheet. Run cg demultiplex samplesheet validate %s",
            flowcell_obj.sample_sheet_path,
        )
        raise click.Abort

    slurm_job_id: int = demultiplex_api.start_demultiplexing(
        flowcell=flowcell_obj)
    tb_api: TrailblazerAPI = context.trailblazer_api
    demultiplex_api.add_to_trailblazer(tb_api=tb_api,
                                       slurm_job_id=slurm_job_id,
                                       flowcell=flowcell_obj)
示例#3
0
def demultiplex_all(context: CGConfig, bcl_converter: str,
                    flowcells_directory: click.Path, dry_run: bool):
    """Demultiplex all flowcells that are ready under the flowcells_directory"""
    LOG.info("Running cg demultiplex all, using %s.", bcl_converter)
    if flowcells_directory:
        flowcells_directory: Path = Path(str(flowcells_directory))
    else:
        flowcells_directory: Path = Path(context.demultiplex.run_dir)
    demultiplex_api: DemultiplexingAPI = context.demultiplex_api
    demultiplex_api.set_dry_run(dry_run=dry_run)
    tb_api: TrailblazerAPI = context.trailblazer_api
    LOG.info("Search for flowcells ready to demultiplex in %s",
             flowcells_directory)
    for sub_dir in flowcells_directory.iterdir():
        if not sub_dir.is_dir():
            continue
        LOG.info("Found directory %s", sub_dir)
        try:
            flowcell_obj = Flowcell(flowcell_path=sub_dir,
                                    bcl_converter=bcl_converter)
        except FlowcellError:
            continue

        if not demultiplex_api.is_demultiplexing_possible(
                flowcell=flowcell_obj) and not dry_run:
            continue

        if not flowcell_obj.validate_sample_sheet():
            LOG.warning(
                "Malformed sample sheet. Run cg demultiplex samplesheet validate %s",
                flowcell_obj.sample_sheet_path,
            )
            continue

        delete_demux_api: DeleteDemuxAPI = DeleteDemuxAPI(
            config=context,
            demultiplex_base=demultiplex_api.out_dir,
            dry_run=dry_run,
            run_path=(flowcells_directory / sub_dir),
        )

        delete_demux_api.delete_flow_cell(
            cg_stats=False,
            demultiplexing_dir=True,
            run_dir=False,
            housekeeper=True,
            init_files=False,
            status_db=False,
        )

        slurm_job_id: int = demultiplex_api.start_demultiplexing(
            flowcell=flowcell_obj)
        demultiplex_api.add_to_trailblazer(tb_api=tb_api,
                                           slurm_job_id=slurm_job_id,
                                           flowcell=flowcell_obj)
def test_no_active_samples_on_flow_cell(
        populated_wipe_demultiplex_api: DeleteDemuxAPI, flowcell_name: str):
    """Test if the function to find no active samples works correctly"""

    # GIVEN a flowcell with no active samples related to it
    store_: Store = populated_wipe_demultiplex_api.status_db
    samples_on_flow_cell: List[Sample] = (store_.query(Flowcell).filter(
        Flowcell.name == flowcell_name).first().samples)
    assert samples_on_flow_cell
    for sample in samples_on_flow_cell:
        active: bool = store_.active_sample(internal_id=sample.internal_id)
        assert not active

    # WHEN checking for active samples on flowcell
    populated_wipe_demultiplex_api._set_samples_on_flow_cell()
    active_samples_on_flow_cell: Optional[List[
        str]] = populated_wipe_demultiplex_api.active_samples_on_flow_cell()

    # THEN the no samples on the flowcell should be found active
    assert not active_samples_on_flow_cell
示例#5
0
def fixture_active_wipe_demultiplex_api(
    active_wipe_demux_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flowcell_full_name: str,
) -> DeleteDemuxAPI:
    """Yield an instantiated DeleteDemuxAPI with active samples on a flowcell"""
    return DeleteDemuxAPI(
        config=active_wipe_demux_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=False,
        run_path=Path(flowcell_full_name),
    )
示例#6
0
def fixture_populated_wipe_demultiplex_api(
    populated_wipe_demux_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    tmp_flow_cell_run_path: Path,
) -> DeleteDemuxAPI:
    """Yield an initialized populated DeleteDemuxAPI"""
    return DeleteDemuxAPI(
        config=populated_wipe_demux_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=False,
        run_path=tmp_flow_cell_run_path,
    )
示例#7
0
def fixture_wipe_demultiplex_api(
    cg_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flowcell_full_name: str,
    stats_api: StatsAPI,
) -> DeleteDemuxAPI:
    """Yield an initialized DeleteDemuxAPI"""
    cg_context.cg_stats_api_ = stats_api
    return DeleteDemuxAPI(
        config=cg_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=False,
        run_path=Path(flowcell_full_name),
    )
def test_delete_flow_cell_housekeeper_only_sample_level(
    caplog,
    cg_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flowcell_full_name: str,
    populated_flow_cell_store: Store,
    sample_level_housekeeper_api: HousekeeperAPI,
    tmp_fastq_paths: List[Path],
):
    """Test function to remove fastqs from Housekeeper when there are only files on sample level
    (not on flow cell name)
    """

    caplog.set_level(logging.INFO)
    cg_context.housekeeper_api_ = sample_level_housekeeper_api
    cg_context.status_db_ = populated_flow_cell_store

    # GIVEN a DeleteDemuxAPI with a HousekeeperAPI with no files with flow cell name as a tag

    sample_level_files: List[Path] = tmp_fastq_paths

    wipe_demultiplex_api: DeleteDemuxAPI = DeleteDemuxAPI(
        config=cg_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=False,
        run_path=Path(flowcell_full_name),
    )
    wipe_demultiplex_api._set_samples_on_flow_cell()

    # WHEN wiping files in Housekeeper

    wipe_demultiplex_api.delete_flow_cell_housekeeper()

    # THEN you should be notified that there are no files on flow cell names

    assert (
        f"Housekeeper: No files found with tag: {wipe_demultiplex_api.flow_cell_name}"
        in caplog.text)

    # AND you should be notified that there were fastq files removed on sample level

    for file in sample_level_files:
        assert f"{file.as_posix()} deleted" in caplog.text
def test_delete_flow_cell_housekeeper_flowcell_name(
    caplog,
    cg_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flow_cell_name_housekeeper_api: HousekeeperAPI,
    flowcell_full_name: str,
    populated_flow_cell_store: Store,
    tmp_fastq_paths: List[Path],
    tmp_sample_sheet_path: Path,
):
    """Test function to remove files from Housekeeper using flow cell name as a tag"""

    caplog.set_level(logging.INFO)
    cg_context.housekeeper_api_ = flow_cell_name_housekeeper_api
    cg_context.status_db_ = populated_flow_cell_store

    # GIVEN

    fastq_files: List[Path] = tmp_fastq_paths
    sample_sheet_file: Path = tmp_sample_sheet_path

    wipe_demultiplex_api: DeleteDemuxAPI = DeleteDemuxAPI(
        config=cg_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=False,
        run_path=Path(flowcell_full_name),
    )
    wipe_demultiplex_api._set_samples_on_flow_cell()

    # WHEN

    wipe_demultiplex_api.delete_flow_cell_housekeeper()

    # THEN

    assert (
        f"Housekeeper: No files found with tag: {wipe_demultiplex_api.flow_cell_name}"
        not in caplog.text)
    assert f"Deleted {sample_sheet_file.as_posix()} from housekeeper" in caplog.text
    for fastq_file in fastq_files:
        assert f"{fastq_file.as_posix()} deleted" in caplog.text
def test_set_dry_run_delete_demux_api(
    caplog,
    cg_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flowcell_full_name: str,
    stats_api: StatsAPI,
):
    """Test to test function to set the API to run in dry run mode"""

    caplog.set_level(logging.DEBUG)
    cg_context.cg_stats_api_ = stats_api
    # WHEN setting the dry_run mode on a DeleteDemuxAPI
    wipe_demultiplex_api: DeleteDemuxAPI = DeleteDemuxAPI(
        config=cg_context,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=True,
        run_path=flowcell_full_name,
    )

    # THEN the dry run parameter should be set to True and it should be logged
    assert wipe_demultiplex_api.dry_run
    assert f"DeleteDemuxAPI: Setting dry run mode to True" in caplog.text
def test_initiate_delete_demux_api(
    caplog,
    cg_context: CGConfig,
    demultiplexed_flowcells_working_directory: Path,
    flowcell_full_name: str,
):
    """Test to initialize the DeleteDemuxAPI"""

    caplog.set_level(logging.DEBUG)

    # GIVEN a correct config
    config = cg_context

    # WHEN initializing the DeleteDemuxAPI
    DeleteDemuxAPI(
        config=config,
        demultiplex_base=demultiplexed_flowcells_working_directory,
        dry_run=True,
        run_path=flowcell_full_name,
    )

    # THEN the API should be correctly initialized
    assert "DeleteDemuxAPI: API initiated" in caplog.text
示例#12
0
def delete_flow_cell(
    context: CGConfig,
    dry_run: bool,
    demultiplexing_dir: str,
    cg_stats: bool,
    demultiplex_base: bool,
    housekeeper: bool,
    init_files: bool,
    run_dir: bool,
    run_directory: str,
    status_db: bool,
    yes: bool,
):
    """Delete a flowcell. If --status-db is passed then all other options will be treated as True"""
    demultiplex_base: Path = Path(demultiplex_base)
    run_path: Path = Path(run_directory)

    wipe_demux_api: DeleteDemuxAPI = DeleteDemuxAPI(
        config=context,
        demultiplex_base=demultiplex_base,
        dry_run=dry_run,
        run_path=run_path)

    if yes or click.confirm(
            f"Are you sure you want to delete the flow cell from the following databases:\n"
            f"cg-stats={True if status_db else cg_stats}\nDemultiplexing-dir={True if status_db else demultiplexing_dir}\n"
            f"Housekeeper={True if status_db else housekeeper}\nInit_files={True if status_db else init_files}\n"
            f"Run-dir={True if status_db else run_dir}\nStatusdb={status_db}"):
        wipe_demux_api.delete_flow_cell(
            cg_stats=cg_stats,
            demultiplexing_dir=demultiplexing_dir,
            housekeeper=housekeeper,
            init_files=init_files,
            run_dir=run_dir,
            status_db=status_db,
        )